thesalegroup / restorm
REST ORM
Requires
- php: ^7.1
- guzzlehttp/guzzle: ^6.0
- ocramius/proxy-manager: ^2.1
- symfony/event-dispatcher: ^3
- symfony/yaml: ^3
This package is auto-updated.
Last update: 2025-03-24 06:06:20 UTC
README
RESTORM
A REST ORM library for persisting data via an HTTP REST API. Inspired by Doctrine, RESTORM provides an entity manager to take care of persisting and loading your entities to and from a REST API.
Feature Overview
- 💾 Load and save entities from a RESTful API
- 👥 Manage data from multiple APIs
- 🔃 Manage unidirectional and bidirectional relationships between entities
- 💤 Effortlessly lazy load associated entities
- 🎈 Automated calls to paginated entities in loops
- 📝 Scalar, objects, and embedded entity types
Documentation Contents
- Installation
- Quick Start
- Basic Usage
- Internals
- References
Installation
To install RESTORM, run the following composer command:
composer install thesalegroup/restorm
If you haven't already done so, add the file autoloader from composer to your project code:
require __DIR__ . '/../vendor/autoload.php';
Quick Start
The example below can be used for reference for setting up a new project with RESTORM. For more information read through the rest of this guide which will link you to more documentation and references.
<?php // Use the composer autoloader to load in RESTORM require __DIR__ . '/../vendor/autoload.php'; use TheSaleGroup\Restorm\Configuration\Configuration; use TheSaleGroup\Restorm\EntityManager; use App\Entity\Post; // Create a new Configuration instance based on our configuration $configPath = '../config/restorm.yml'; $configuration = Configuration::buildFromYaml($configPath); // Create a new EntityManager from our Configuration instance $entityManager = EntityManager::createFromConfiguration($configuration); // Fetch all the posts from the API $posts = $entityManager->getRepository(Post::class)->findAll(); // Loop over the collection of posts to see their data foreach($posts as $post) { // Instances of Author are lazy loaded when you need them. $author = $post->getAuthor() // Returns an instance of Author // No request is made to the API for the author until you request // data that wasn't available in the initial request. // The following request will not trigger a new call … $authorId = $author->getId(); // …whereas this one will quietly populate the rest of Author $authorName = $author->getName(); }
Basic Usage
The following steps will show you a very simple usage of RESTORM for a project.
We will setup RESTORM to talk to an artificial endpoint at
https://example.com/api
which serves a RESTful API. For this example we're
going to create a very simple set of entities that would be useful for a blog.
These will include a Post
entity which has an Author
entity associated with
it.
Create Entities
To start off we'll create some classes for our entities. An entity is simply a
resource object that's managed by RESTORM. An entity has properties which are
populated from RESTful API calls as well as any other methods or logic you wish
to have in them. Let's create a simple Post
class:
<?php # src/Entity/Post.php namespace App\Entity; class Post { private $id; private $title; public $content; private $author; public function getId(): ?int { return $this->id; } public function getAuthor(): ?Author { return $this->author; } public function getTitle(): ?string { return $this->title; } }
Entities are not required to extend any interfaces or classes in RESTORM - any
class can become an entity. Notice as well that the Post::$id
,
Post::$title
, and Post::$author
are all private properties - this will not
affect RESTORM's ability to manage these fields as it manages properties
through reflection.
In our Post
entity the "ID", "title", and "content" will all be simple scalar
values from our API, but "author" is different; although this will be in
integer in the API that represent the ID of an author, we'll instead want this
property to be populated with an instance of Author
. Before we create our
configuration to do manage this and the other fields, let's create the Author
class as well:
<?php # src/Entity/Author.php namespace App\Entity; class Author { private $id; private $name; public function getId(): ?int { return $this->id; } public function getName(): ?string { return $this->name; } }
Create Configuration File
With our entity classes defined now it's time to move on to creating the
configuration file. For this we're going to needs to know what URLs we need to
call to get our entity data and what properties need populating on our
entities. Let's assume for this example that we're going to need to talk to a
RESTful endpoint at https://example.com/api
. We'll add in the the following
configuration file that will set up the connection details and the entity
mappings:
connections: # Define a connection which describes where we get entities from default: # The base URI is going to include the /api path as this # is universal for all endpoints on this connection base_uri: https://example.com/api # Let RESTORM know what the parameters are for using # pagination with list endpoints pagination_parameters: page_param: page per_page_param: per_page # Define the Post and Author entities entity_mappings: # Use the fully qualified entity class name as the key App\Entity\Post: # Use our "default" connection we registered above connection: default # Use the internal entity repository for querying # for entities repository_class: TheSaleGroup\Restorm\EntityRepository # Define the paths to each of the actions used for # getting and saving entities paths: list: /posts get: /posts/{id} post: /posts/new patch: /posts/{id}/edit delete: posts/{id} # List our properties properties: id: # Let RESTORM know that the id is the identifier identifier: true type: integer title: type: string unique: true content: type: string # The content property is called "html_content" # in the API so map that to the "content" # property in the entity map_from: html_content # Relate a Post entity to an Author entity author: # We will set the type as "entity"… type: entity # …and set the entity class entity: Project\Entity\Author Project\Entity\Author: connection: default repository_class: TheSaleGroup\Restorm\EntityRepository paths: list: /authors get: /authors/{username} post: /authors patch: /authors/{username} delete: /authors/{username} properties: id: identifier: true type: integer name: type: string
You can view the full configuration reference here:
Initialize Manager
The entity manager is the heart of RESTORM. It controls entities as they go to
and from the connections and connects each internal component. Let's create a
simple script that creates a new EntityManager
and fetches all our posts:
<?php // Use the composer autoloader to load in RESTORM require __DIR__ . '/../vendor/autoload.php'; use TheSaleGroup\Restorm\Configuration\Configuration; use TheSaleGroup\Restorm\EntityManager; use App\Entity\Post; // Create a new Configuration instance based on our configuration $configPath = '../config/restorm.yml'; $configuration = Configuration::buildFromYaml($configPath); // Create a new EntityManager from our Configuration instance $entityManager = EntityManager::createFromConfiguration($configuration);
With the EntityManager
instantiated it can now be used to fetch entites:
// Fetch all the posts from the API $posts = $entityManager->getRepository(Post::class)->findAll(); // Loop over the collection of posts to see their data foreach($posts as $post) { // Instances of Author are lazy loaded when you need them. $author = $post->getAuthor() // Returns an instance of Author // No request is made to the API for the author until you request // data that wasn't available in the initial request. // The following request will not trigger a new call … $authorId = $author->getId(); // …whereas this one will quietly populate the rest of Author $authorName = $author->getName(); }