-
Notifications
You must be signed in to change notification settings - Fork 67
Schemas
A Schema is a class that implements SchemaInterface and provides information on how an arbitrary resource object(s) (class, Model, etc) should be converted to JSON API format. It gives
- Information about resource attributes.
- Information about resource relationships to other resources.
- Resource id, JSON API type and URL.
- Conversion settings (e.g. if
selfandrelatedURLs should be shown, if meta information should be shown, if relationships should be shown as URLs, etc). - Information what relationships should be placed to included section for each resource type independently.
- Relationship pagination links.
Sample Schema
class AuthorSchema extends BaseSchema
{
public function getType(): string
{
return 'people';
}
public function getId($author): ?string
{
return $author->authorId;
}
public function getAttributes($author): iterable
{
return [
'first-name' => $author->firstName,
'last-name' => $author->lastName,
];
}
public function getRelationships($author): iterable
{
return [
'comments' => [
self::RELATIONSHIP_DATA => $author->comments,
self::RELATIONSHIP_LINKS_SELF => false,
self::RELATIONSHIP_LINKS_RELATED => true,
],
];
}
}A schema typically defines
- a resource JSON API type in
getTypemethod. - a resource identifier in
getIdmethod - resource attributes in
getAttributesand relationships ingetRelationships
Suppose you have a data row from a database for model Comment and this row has a column id_author which is a foreign key that refers to other table named authors. You do not have all the columns for the author but you want the comment to have author relationship. You can return IdentifierInterface instance in self::RELATIONSHIP_DATA. For example,
use Neomerx\JsonApi\Schema\Identifier;
class CommentSchema extends BaseSchema
{
...
public function getRelationships($comment): iterable
{
return [
'author' => [
self::RELATIONSHIP_DATA => new Identifier($comment->id_author, 'people'),
],
];
}
}self and related URLs could be shown/hidden for each relationship individually with self::RELATIONSHIP_LINKS_SELF and self::RELATIONSHIP_LINKS_RELATED parameters
class SiteSchema extends BaseSchema
{
...
public function getRelationships($site): : iterable
{
/** @var Site $site */
return [
...
'posts' => [
self::RELATIONSHIP_DATA => $site->posts,
self::RELATIONSHIP_LINKS_SELF => true,
self::RELATIONSHIP_LINKS_RELATED => true
],
...
];
}
...
}An example below shows self and related links in relationships
{
"data": {
"type": "sites",
"id": "1",
"attributes": { ... },
"relationships": {
"posts": {
"data": { "type": "posts", "id": "321" },
"links": {
"self": "http://example.com/sites/1/relationships/posts",
"related": "http://example.com/sites/1/posts"
}
}
}
...
}
}self::RELATIONSHIP_LINKS_SELF and self::RELATIONSHIP_LINKS_RELATED override default values returned by isAddSelfLinkInRelationshipByDefault and isAddRelatedLinkInRelationshipByDefault of SchemaInterface.
Links could be added to relationships with self::RELATIONSHIP_LINKS key
class SiteSchema extends BaseSchema
{
...
public function getRelationships($site): : iterable
{
/** @var Site $site */
return [
...
'posts' => [
self::RELATIONSHIP_DATA => $site->posts,
self::RELATIONSHIP_LINKS => [
LinkInterface::FIRST => new Link(false,'http://example.com/posts?first', false),
'custom-link' => new Link(false,'http://example.com/custom-link', false),
]
],
...
];
}
...
}Links could be defined with absolute URLs (e.g. http://example.com/posts/first) or relative sub URLs (e.g. /first). For more information see Links.
Default links (e.g. related) can also be overriden here with a customized Link.
Links could be added to relationships with self::RELATIONSHIP_META key
class SiteSchema extends BaseSchema
{
...
public function getRelationships($site): : iterable
{
/** @var Site $site */
return [
...
'posts' => [
self::RELATIONSHIP_META => ['description' => 'any meta information'],
],
...
];
}
...
}Meta information for resources could be added to various places such as resource itself, individual relationships, etc. The following json document illustrates those places
{
"meta": {"here": "document meta"},
"data":{
"type":"posts",
"id":"1",
"attributes":{
},
"relationships":{
"author":{
"data":{
"type":"people",
"id":"9",
"meta": {"here": "linkage meta"}
},
"meta": {"here": "relationship meta"}
}
},
"meta": {"here": "resource meta"}
}
}SchemaInterface has the following methods to define meta information
- Encoder
withMetaandwithJsonApiMetacould be used to add document meta information. - Schema
hasIdentifierMeta,getIdentifierMeta,hasResourceMetaandgetResourceMetacould be used to add linkage and resource meta information. - Schema relationship
self::RELATIONSHIP_METAkey is used to add relationship meta information. -
LinkandLinkWithAliasescan be used to add meta information in links.