-
Notifications
You must be signed in to change notification settings - Fork 65
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
self
andrelated
URLs 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
getType
method. - a resource identifier in
getId
method - resource attributes in
getAttributes
and 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
withMeta
andwithJsonApiMeta
could be used to add document meta information. - Schema
hasIdentifierMeta
,getIdentifierMeta
,hasResourceMeta
andgetResourceMeta
could be used to add linkage and resource meta information. - Schema relationship
self::RELATIONSHIP_META
key is used to add relationship meta information. -
Link
andLinkWithAliases
can be used to add meta information in links.