Skip to content
neomerx edited this page Feb 5, 2019 · 14 revisions

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 and related 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 in getRelationships

Show Identifiers in Relationships

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'),
            ],
        ];
    }
}

Show/Hide 'self' and 'related' URLs in Relationships

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.

Show Links in Relationships

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.

Show Meta in Relationships

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

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 and withJsonApiMeta could be used to add document meta information.
  • Schema hasIdentifierMeta, getIdentifierMeta, hasResourceMeta and getResourceMeta could be used to add linkage and resource meta information.
  • Schema relationship self::RELATIONSHIP_META key is used to add relationship meta information.
  • Link and LinkWithAliases can be used to add meta information in links.