Introduction¶
The landscape of API strategies grows every day. In the field of PHP there are strategies from simple REST-only resources to fully Richardson Maturity Model Level 3 API engines. Apigility falls into the Level 3 category. As a contributing author of Apigility and the primary author of Doctrine in Apigility I’ve designed a method to serve ORM data though an API in a white-gloved approach to handling the data.
What do I mean by a “white-gloved approach”? Thanks to the large number of open source libraries for Zend Framework and Apigility the direct manipulation of data is not usually necessary. Certainly there will be times you’ll want to add a user to an entity before it is persisted but the majority of validation and filtering is handled inside Apigility. Doctrine is a powerful ORM and the integration with Apigility is very clean when implemented correctly. This book will instruct you how to do just that.
When should you use Doctrine in Apigility?¶
When you have a Doctrine project with properly mapped associations (metadata) between entities Doctrine in Apigility will give you a powerful head-start toward building an API. Correct metadata is absolutly core to building an API with this tool. To help design your ORM Skipper is strongly recommended. See Entity Relationship Diagramming with Skipper
You can use Doctrine in Apigility to serve pieces of your schema by filtering with hydrator strategies or you can
serve your entire schema in an “Open-schema API” where relationships between entities are fully explored in the HAL
_embedded
data.
If you’re familiar with the benefits of ORM and will use it in your project and you require a fully-fledged API engine then this API strategy may what you’re looking for.
What makes Doctrine in Apigility different?¶
Because Doctrine is an object relational mapper the relationships between entities are part of the Doctrine metadata.
So when a Doctrine entity is extracted with a hydrator the relationships are pulled from the entity too and included in the
HAL response as _embedded
data and naturally create a HATEOAS response.
By using hydration strategies you may include just a
link to the canonical resource or embed the entire resource and in turn embed its resources.
Consider this response to a request for an Artist
{
"id": 1,
"name": "Soft Cell",
"_embedded": {
"album": [
{
"id": 1,
"name": "Non-Stop Erotic Cabaret",
"_embedded": {
"artist": {
"_links": {
"self": "https://api/artist/1"
}
},
"song": {
"_links": {
"self": "https://api/song?filter%5B0%5D%5Bfield%5D=album&filter%5B0%5D%5Btype%5D=eq&filter%5B0%5D%5Bvalue%5D=1"
}
}
},
"_links": {
"self": "https://api/album/1"
}
}
],
},
"_links": {
"self": "https://api/artist/1"
}
}
The album
collection for this artist is returned because a CollectionExtract
hydration strategy was used.
Inside the album
, instead of including every song
, just a link to the collection filtered by the album
is included. This way a consumer of the API is directed how to fetch the data when it is not included.
Each album entry has an embedded artist
but this would cause a cyclic reference so an EntityLink
hydrator is
used to just give a link to the artist
from within an album
. This is common when using the CollectionExtract
hydrator.
Within each API response when using Doctrine in Apigility there will never be a dead-end. Any reference to an entity or collection will be handled by a hydrator thereby making the API fully implement HATEOAS.
Note
Authored by API Skeletons. All rights reserved.