### Install Neomerx JSON API Source: https://github.com/neomerx/json-api/blob/master/sample/README.md Installs the Neomerx JSON API application using Composer. This command fetches and installs all necessary dependencies for the project. ```shell $ composer install ``` -------------------------------- ### Install neomerx/json-api via Composer Source: https://github.com/neomerx/json-api/wiki/Home This snippet shows the command to install the neomerx/json-api library using Composer, the standard package manager for PHP. It ensures all necessary dependencies are downloaded and configured for your project. ```shell $ composer require neomerx/json-api ``` -------------------------------- ### PHP Schema for Author Resource Source: https://github.com/neomerx/json-api/wiki/Schemas Demonstrates a basic PHP Schema implementation for an Author resource, defining its JSON API type, ID, attributes, and relationships. This serves as a foundational example for resource representation. ```php 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, ], ]; } } ``` -------------------------------- ### Article Resource Example Source: https://github.com/neomerx/json-api/blob/master/spec/current.txt Illustrates a JSON:API resource object for an article, including attributes, links, and a relationship to an author. This example shows how to represent a single resource with its associated metadata and relationships. ```JSON { "type": "articles", "id": "1", "attributes": { "title": "Rails is Omakase" }, "relationships": { "author": { "links": { "self": "http://example.com/articles/1/relationships/author", "related": "http://example.com/articles/1/author" }, "data": { "type": "people", "id": "9" } } }, "links": { "self": "http://example.com/articles/1" } } ``` -------------------------------- ### JSON:API Document Structure Example Source: https://github.com/neomerx/json-api/blob/master/spec/current.txt Illustrates a basic JSON:API document structure, showing the top-level members like 'data', 'links', and 'jsonapi'. This example demonstrates how primary data and metadata are organized. ```JSON { "data": { "type": "articles", "id": "1", "attributes": { "title": "JSON API paints my bikeshed!", "isDraft": true }, "relationships": { "author": { "links": { "self": "/articles/1/relationships/author", "related": "/articles/1/author" }, "data": { "type": "people", "id": "9" } } } }, "links": { "self": "http://example.com/articles/1" }, "jsonapi": { "version": "1.0" } } ``` -------------------------------- ### JSON API Relationship Links Example Source: https://github.com/neomerx/json-api/wiki/Schemas An example JSON structure illustrating how 'self' and 'related' links are represented within a resource's relationship object in a JSON API document. ```json { "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" } } } ... } } ``` -------------------------------- ### Namespace Refactoring for Links and Encoding Parameters Source: https://github.com/neomerx/json-api/wiki/Upgrade-Notes Several interfaces and classes related to Links and Encoding Parameters have been moved to new namespaces for better organization and clarity. This includes `LinkInterface`, `Link`, `EncodingParametersInterface`, and `EncodingParameters`. ```APIDOC Namespace Changes - LinkInterface: Moved from `Neomerx\JsonApi\Contracts\Schema` to `Neomerx\JsonApi\Contracts\Document`. - Link: Moved from `Neomerx\JsonApi\Schema` to `Neomerx\JsonApi\Document`. - EncodingParametersInterface: Moved from `Neomerx\JsonApi\Contracts\Http\Parameters` to `Neomerx\JsonApi\Contracts\Encoder`. - EncodingParameters: Moved from `Neomerx\JsonApi\Http\Parameters` to `Neomerx\JsonApi\Encoder\Parameters`. - Description: These namespace changes are part of a broader effort to improve the project's structure and adhere to common conventions, facilitating better code management and discoverability. - Related Issue: https://github.com/neomerx/json-api/issues/124 ``` -------------------------------- ### Schema::$selfSubUrl Format Change Source: https://github.com/neomerx/json-api/wiki/Upgrade-Notes The `$selfSubUrl` property within the `Schema` class now requires a specific format: it must only start with a slash, without an ending slash. If not manually set, it defaults to `$this->resourceType` prefixed with a single slash. This adjustment standardizes URL construction for schema-related links. ```APIDOC Schema::$selfSubUrl Property - Format Requirement: Must start with a slash ('/'), but not end with one. - Default Value (if not set): '/' . $this->resourceType - Description: The `$selfSubUrl` property in the `Schema` class has been updated to enforce a specific format for the starting slash. If you manually set this property, ensure it adheres to the new format. If left unset, it will be automatically composed with a leading slash. - Related Issue: https://github.com/neomerx/json-api/issues/123 ``` -------------------------------- ### Encoder Parameters for Links, Meta, and API Version Source: https://github.com/neomerx/json-api/wiki/Upgrade-Notes Passing Links, Meta, and JSON API version information via `Encoder` parameters has been deprecated and removed. These should now be passed using dedicated `with...` methods on the `Encoder` instance. ```APIDOC Encoder Parameter Handling for Links, Meta, and API Version - Deprecated Method: Passing Links, Meta, and JSON API version via `Encoder` parameters. - Recommended Method: Use `with...` methods on the `Encoder` instance. - Example: ```php $encoder ->withLinks($links) ->withMeta($docMeta) ->withJsonApiVersion($versionMeta) ->encodeData(...); ``` - Description: This change modernizes how metadata and versioning information is attached to the encoded JSON API output, promoting a more fluent and explicit API usage pattern. ``` -------------------------------- ### JSON API Document Structure with Meta Information Source: https://github.com/neomerx/json-api/wiki/Schemas Illustrates the structure of a JSON API document, highlighting where meta objects can be placed for the document itself, individual resources, and specific relationships. This follows the JSON API specification for metadata. ```json { "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"} } } ``` -------------------------------- ### JSON API Resource Creation (POST) Source: https://github.com/neomerx/json-api/blob/master/spec/current.txt Describes how to create a resource by sending a POST request to a collection URL. The request must include a resource object with at least a 'type' member. Examples show basic creation and creation with client-generated IDs. ```APIDOC POST /photos HTTP/1.1 Content-Type: application/vnd.api+json Accept: application/vnd.api+json { "data": { "type": "photos", "attributes": { "title": "Ember Hamster", "src": "http://example.com/images/productivity.png" }, "relationships": { "photographer": { "data": { "type": "people", "id": "9" } } } } } ``` ```APIDOC POST /photos HTTP/1.1 Content-Type: application/vnd.api+json Accept: application/vnd.api+json { "data": { "type": "photos", "id": "550e8400-e29b-41d4-a716-446655440000", "attributes": { "title": "Ember Hamster", "src": "http://example.com/images/productivity.png" } } } ``` -------------------------------- ### JSON:API Resource Deletion Example Source: https://github.com/neomerx/json-api/blob/master/spec/current.txt Illustrates a DELETE request to remove an individual resource, specifying the request headers and detailing the possible HTTP responses for successful deletion or resource not found. ```APIDOC DELETE /photos/1 HTTP/1.1 Accept: application/vnd.api+json Responses: 202 Accepted: If a deletion request has been accepted for processing, but the processing has not been completed by the time the server responds, the server MUST return a 202 Accepted status code. 204 No Content: A server MUST return a 204 No Content status code if a deletion request is successful and no content is returned. 200 OK: A server MUST return a 200 OK status code if a deletion request is successful and the server responds with only top-level meta data. 404 NOT FOUND: A server SHOULD return a 404 Not Found status code if a deletion request fails due to the resource not existing. Other Responses: A server MAY respond with other HTTP status codes. A server MAY include error details with error responses. A server MUST prepare responses, and a client MUST interpret responses, in accordance with HTTP semantics. ``` -------------------------------- ### JSON API Author Resource Structure Source: https://github.com/neomerx/json-api/blob/master/README.md An example of the expected JSON API output for an author resource. This structure includes the resource type, ID, attributes, relationships, and self-links as defined by the JSON API specification. ```json { "data" : { "type" : "people", "id" : "123", "attributes" : { "first-name": "John", "last-name": "Doe" }, "relationships" : { "comments" : { "links": { "related" : "http://example.com/api/v1/people/123/comments" } } }, "links" : { "self" : "http://example.com/api/v1/people/123" } } } ``` -------------------------------- ### PHP Schema Relationship Example Source: https://github.com/neomerx/json-api/wiki/Extending-Encoder Demonstrates how to define relationships in a PHP JSON:API schema, specifically handling cases where a relationship might return a proxy object extending the expected class. This example shows how to configure the encoder to map these proxy classes to their corresponding schema classes. ```PHP class PostSchema extends BaseSchema { ... public function getRelationships($post): iterable { return [ 'author' => [ // will not return an Author object but // AuthorProxy which extends Author self::RELATIONSHIP_DATA => $post->getAuthor() ] ]; } ... } ``` ```PHP $encoder = Encoder::instance([ Author::class => AuthorSchema::class, AuthorProxy::class => AuthorSchema::class, ]); ``` -------------------------------- ### Implement Resource Link Methods (`getResourceLinks`, `getIncludedResourceLinks`) Source: https://github.com/neomerx/json-api/wiki/Upgrade-Notes Replaces the `$isShowSelf` and `$isShowSelfInIncluded` properties with `getResourceLinks` and `getIncludedResourceLinks` methods. These methods provide default implementations for generating resource links, allowing for customization of self-link inclusion in primary resources and included resources. ```php public function getResourceLinks($resource) { $links = [ LinkInterface::SELF => $this->getSelfSubLink($resource), ]; return $links; } public function getIncludedResourceLinks($resource) { return []; } ``` -------------------------------- ### JSON:API Resource and Relationship Fetching Source: https://github.com/neomerx/json-api/blob/master/spec/current.txt Details the JSON:API specification for fetching resources and relationships, including request formats, response codes, and example payloads for collections, individual resources, and relationship data. ```APIDOC Resource Fetching: A server MUST support fetching resource data for every URL provided as: - a self link as part of the top-level links object - a self link as part of a resource-level links object - a related link as part of a relationship-level links object Request Examples: Fetching a collection of articles: GET /articles HTTP/1.1 Accept: application/vnd.api+json Fetching an article: GET /articles/1 HTTP/1.1 Accept: application/vnd.api+json Fetching an article’s author (related resource): GET /articles/1/author HTTP/1.1 Accept: application/vnd.api+json Responses for Resource Fetching: 200 OK: - For a successful request to fetch an individual resource or resource collection. - MUST respond with an array of resource objects or an empty array ([]) for resource collections. - MUST respond with a resource object or null for individual resources. Example: 200 OK - Successful Collection Response HTTP/1.1 200 OK Content-Type: application/vnd.api+json { "links": { "self": "http://example.com/articles" }, "data": [ { "type": "articles", "id": "1", "attributes": { "title": "JSON:API paints my bikeshed!" } }, { "type": "articles", "id": "2", "attributes": { "title": "Rails is Omakase" } } ] } Example: 200 OK - Empty Collection Response HTTP/1.1 200 OK Content-Type: application/vnd.api+json { "links": { "self": "http://example.com/articles" }, "data": [] } Example: 200 OK - Successful Individual Resource Response HTTP/1.1 200 OK Content-Type: application/vnd.api+json { "links": { "self": "http://example.com/articles/1" }, "data": { "type": "articles", "id": "1", "attributes": { "title": "JSON:API paints my bikeshed!" }, "relationships": { "author": { "links": { "related": "http://example.com/articles/1/author" } } } } } Example: 200 OK - Individual Resource Response (null for empty relationship) HTTP/1.1 200 OK Content-Type: application/vnd.api+json { "links": { "self": "http://example.com/articles/1/author" }, "data": null } 404 Not Found: - MUST respond with 404 Not Found when processing a request to fetch a single resource that does not exist, unless a 200 OK with null is warranted. Other Responses: - MAY respond with other HTTP status codes. - MAY include error details with error responses. - MUST prepare responses, and a client MUST interpret responses, in accordance with HTTP semantics. Fetching Relationships: A server MUST support fetching relationship data for every relationship URL provided as a self link as part of a relationship’s links object. Request Examples: Fetching data about an article’s comments (to-many relationship): GET /articles/1/relationships/comments HTTP/1.1 Accept: application/vnd.api+json Fetching data about an article’s author (to-one relationship): GET /articles/1/relationships/author HTTP/1.1 Accept: application/vnd.api+json Responses for Fetching Relationships: 200 OK: - MUST respond with a 200 OK response for a successful request to fetch a relationship. - Primary data MUST match the appropriate value for resource linkage. - Top-level links object MAY contain self and related links. Example: 200 OK - To-One Relationship Response HTTP/1.1 200 OK Content-Type: application/vnd.api+json { "links": { "self": "/articles/1/relationships/author", "related": "/articles/1/author" }, "data": { "type": "people", "id": "12" } } Example: 200 OK - Empty To-One Relationship Response HTTP/1.1 200 OK Content-Type: application/vnd.api+json { "links": { "self": "/articles/1/relationships/author", "related": "/articles/1/author" }, "data": null } Example: 200 OK - To-Many Relationship Response HTTP/1.1 200 OK Content-Type: application/vnd.api+json { "links": { "self": "/articles/1/relationships/tags", "related": "/articles/1/tags" }, "data": [ { "type": "tags", "id": "2" }, { "type": "tags", "id": "3" } ] } ``` -------------------------------- ### Response Creation Refactoring and Error Handling Improvements Source: https://github.com/neomerx/json-api/wiki/Upgrade-Notes The `Responses` class for HTTP Response creation has been significantly refactored to offer a comprehensive range of JSON API responses. New classes like `JsonApiException` and `ErrorCollection` have been introduced to enhance error handling capabilities. PSR-3 logging support has also been added. ```APIDOC Response Creation and Error Handling Enhancements - Responses Class Refactoring: The `Responses` class now provides a full suite of JSON API responses and includes abstract methods for easier integration with different frameworks. - Error Handling: Introduced `JsonApiException` and `ErrorCollection` classes to improve error management. - PSR-3 Logging: Added support for PSR-3 compliant logging. - Description: These updates focus on making the library more flexible, robust, and easier to integrate, particularly in how API responses are generated and how errors are managed and logged. - Related Issues: https://github.com/neomerx/json-api/issues/111, https://github.com/neomerx/json-api/issues/110, https://github.com/neomerx/json-api/issues/112 ``` -------------------------------- ### JSON:API Meta Object Example Source: https://github.com/neomerx/json-api/blob/master/spec/current.txt Demonstrates the use of a 'meta' member in a JSON:API document. Meta objects can contain any non-standard meta-information, such as copyright notices or author lists, providing flexibility for additional data. ```JSON { "meta": { "copyright": "Copyright 2015 Example Corp.", "authors": [ "Yehuda Katz", "Steve Klabnik", "Dan Gebhardt", "Tyler Kellen" ] }, "data": { // ... resource object(s) } } ``` -------------------------------- ### Resource Identifier Object Example Source: https://github.com/neomerx/json-api/blob/master/spec/current.txt Demonstrates a JSON:API resource identifier object, which uniquely identifies a resource by its type and ID. This object is used for resource linkage in relationships and compound documents. ```JSON { "type": "people", "id": "9" } ``` -------------------------------- ### HTTP Classes Refactoring and PSR-7 Integration Source: https://github.com/neomerx/json-api/wiki/Upgrade-Notes HTTP classes for parsing and checking headers/query parameters have been refactored for better structure. Notably, homegrown HTTP interfaces have been replaced with PSR-7 standards, specifically `PsrHttpMessageServerRequestInterface`. The `EncodingParameters` class now consolidates all HTTP query string parameters. ```APIDOC HTTP Class Refactoring and PSR-7 Integration - PSR-7 Compliance: Replaced internal HTTP interfaces with PSR-7 standards (e.g., `PsrHttpMessageServerRequestInterface`). - EncodingParameters Consolidation: The `EncodingParameters` class now centralizes all parameters originating from the HTTP query string, including pagination, filters, and sorting. - Namespace Update: `EncodingParameters` moved from `\Neomerx\JsonApi\Encoder\EncodingParameters` to `\Neomerx\JsonApi\Encoder\Parameters\EncodingParameters`. - Header Parameters: HTTP header related methods were moved from `ParametersInterface` to `HeaderParametersInterface` (`\Neomerx\JsonApi\Contracts\Http\Headers\HeaderParametersInterface`). - Query Parameters: All HTTP query related methods from `ParametersInterface` were merged into `EncodingParametersInterface`. - Description: These changes aim to improve the library's adherence to industry standards, enhance modularity, and simplify the integration with various PHP frameworks. Developers using the HTTP part of the package will need to adapt to these changes. - Related Issue: https://github.com/neomerx/json-api/issues/109, https://github.com/neomerx/json-api/issues/125 ``` -------------------------------- ### PHP: Schema Changes for Resource Type and Relationships (v3.0 Migration) Source: https://github.com/neomerx/json-api/wiki/Upgrade-Notes Migrating to version 3.0 involves declaring the resource type with the `getType(): string` method and renaming relationship constants. The `getAttributes` and `getRelationships` signatures have also been simplified, and the `Link` constructor was updated. ```php // Example of getType() method class YourSchema extends BaseSchema { public function getType(): string { return 'your-resource-type'; } // ... other methods } // Relationship constant renaming example: // self::DATA -> self::RELATIONSHIP_DATA // self::SHOW_SELF -> self::RELATIONSHIP_LINKS_SELF // self::SHOW_RELATED -> self::RELATIONSHIP_LINKS_RELATED ``` -------------------------------- ### JSON API PATCH Request Examples Source: https://github.com/neomerx/json-api/blob/master/spec/current.txt This documentation details how to construct PATCH requests for updating resources according to the JSON API specification. It covers updating attributes, relationships (to-one and to-many), and expected server responses, including status codes and error conditions. ```APIDOC PATCH Request Structure: A PATCH request MUST include a single resource object as primary data. The resource object MUST contain type and id members. Example: Updating a Resource's Attributes PATCH /articles/1 HTTP/1.1 Content-Type: application/vnd.api+json Accept: application/vnd.api+json { "data": { "type": "articles", "id": "1", "attributes": { "title": "To TDD or Not" } } } If a request does not include all of the attributes for a resource, the server MUST interpret the missing attributes as if they were included with their current values. The server MUST NOT interpret missing attributes as null values. Example: Updating Multiple Attributes PATCH /articles/1 HTTP/1.1 Content-Type: application/vnd.api+json Accept: application/vnd.api+json { "data": { "type": "articles", "id": "1", "attributes": { "title": "To TDD or Not", "text": "TLDR; It's complicated... but check your test coverage regardless." } } } Example: Updating a Resource’s Relationships (To-One) If a relationship is provided in the relationships member of a resource object in a PATCH request, its value MUST be a relationship object with a data member. The relationship’s value will be replaced with the value specified in this member. PATCH /articles/1 HTTP/1.1 Content-Type: application/vnd.api+json Accept: application/vnd.api+json { "data": { "type": "articles", "id": "1", "relationships": { "author": { "data": { "type": "people", "id": "1" } } } } } Example: Updating a Resource’s Relationships (To-Many - Full Replacement) A server MAY reject an attempt to do a full replacement of a to-many relationship. In such a case, the server MUST reject the entire update, and return a 403 Forbidden response. PATCH /articles/1 HTTP/1.1 Content-Type: application/vnd.api+json Accept: application/vnd.api+json { "data": { "type": "articles", "id": "1", "relationships": { "tags": { "data": [ { "type": "tags", "id": "2" }, { "type": "tags", "id": "3" } ] } } } } Responses: 202 Accepted: If an update request has been accepted for processing, but the processing has not been completed by the time the server responds, the server MUST return a 202 Accepted status code. 200 OK: If a server accepts an update but also changes the resource(s) in ways other than those specified by the request (for example, updating the updated-at attribute or a computed sha), it MUST return a 200 OK response. The response document MUST include a representation of the updated resource(s) as if a GET request was made to the request URL. A server MUST return a 200 OK status code if an update is successful, the client’s current attributes remain up to date, and the server responds only with top-level meta data. In this case the server MUST NOT include a representation of the updated resource(s). 204 No Content: If an update is successful and the server doesn’t update any attributes besides those provided, the server MUST return either a 200 OK status code and response document (as described above) or a 204 No Content status code with no response document. 403 Forbidden: A server MUST return 403 Forbidden in response to an unsupported request to update a resource or relationship. 404 Not Found: A server MUST return 404 Not Found when processing a request to modify a resource that does not exist. A server MUST return 404 Not Found when processing a request that references a related resource that does not exist. 409 Conflict: A server MAY return 409 Conflict when processing a PATCH request to update a resource if that update would violate other server-enforced constraints (such as a uniqueness constraint on a property other than id). A server MUST return 409 Conflict when processing a PATCH request in which the resource object’s type and id do not match the server’s endpoint. A server SHOULD include error details and provide enough information to recognize the source of the conflict. ``` -------------------------------- ### Schema::getRelationships Manual Link Handling Source: https://github.com/neomerx/json-api/wiki/Upgrade-Notes When manually adding relative links within the `getRelationships` method of the `Schema` class, relative paths must now be prefixed with the result of `$this->getSelfSubUrl($resource)`. This change ensures correct path construction for relative links, improving consistency and support for nested resources. ```APIDOC Schema::getRelationships Manual Link Addition - Old Format: 'boo' => new Link('some/link') - New Format: 'boo' => new Link($this->getSelfSubUrl($resource) . '/some/link') - Description: For manual `Link` additions in `getRelationships` that use relative paths, the path must now be explicitly prefixed with the result of `$this->getSelfSubUrl($resource)`. This ensures that relative links are correctly resolved in the context of the resource. - Related Issue: https://github.com/neomerx/json-api/issues/119 ``` -------------------------------- ### PHP: Add Strong Typing to Schema Methods (v2.0 Migration) Source: https://github.com/neomerx/json-api/wiki/Upgrade-Notes Version 2.0 introduced PHP strong types to applicable interface and class methods. Key methods like `getId`, `getAttributes`, and `getRelationships` received type hints for parameters and return values, requiring updates for stricter type checking. ```php class YourSchema extends BaseSchema { public function getId($resource): ?string { // `: ?string` is added return $resource->getId(); } public function getAttributes($resource, array $fieldKeysFilter = null): ?array { // `array $fieldKeysFilter = null` and `: ?array` are added return $resource->getAttributes($fieldKeysFilter); } public function getRelationships($resource, bool $isPrimary, array $includeRelationships): ?array { // `: ?array` is added return $resource->getRelationships($isPrimary, $includeRelationships); } } ``` -------------------------------- ### PHP: Add ContextInterface to Schema Methods (v4.0 Migration) Source: https://github.com/neomerx/json-api/wiki/Upgrade-Notes For migration to version 4.0, the `SchemaInterface::getAttributes` and `SchemaInterface::getRelationships` methods require an additional `ContextInterface` parameter. This context provides extra information about the resource and encoder options, potentially enabling smarter resource loading. ```php use Neomerx\JsonApi\Contracts\Schema\ContextInterface; class YourSchema extends BaseSchema { // ... // add `ContextInterface $context` public function getAttributes($author, ContextInterface $context): iterable { } // add `ContextInterface $context` public function getRelationships($resource, ContextInterface $context): iterable { } } ``` -------------------------------- ### Schema::selfSubUrl Default Value Example Source: https://github.com/neomerx/json-api/wiki/Upgrade-Notes Illustrates the default construction of the `$selfSubUrl` property in the `Schema` class when it is not explicitly set. The default value is constructed by prepending a slash to the `resourceType`. ```PHP $this->selfSubUrl = '/' . $this->resourceType . '/'; ``` -------------------------------- ### Run Neomerx JSON API Samples Source: https://github.com/neomerx/json-api/blob/master/sample/README.md Executes the sample application to demonstrate encoding results for various JSON API features. It showcases resources with and without relationships, sparse and field set filters, and top-level links and meta information. ```shell $ php sample.php ``` -------------------------------- ### Create JSON API Encoder Instance with Schemas Source: https://github.com/neomerx/json-api/wiki/Home Demonstrates how to create an instance of the JSON API Encoder by providing an array of schema mappings. Schemas define how resource objects are converted to JSON API format, mapping resource types to their corresponding schema classes or callables. ```php use Neomerx\JsonApi\Contracts\Encoder\EncoderInterface; use Neomerx\JsonApi\Encoder\Encoder; // Assuming Author, Comment, Post, Site are your domain classes // and AuthorSchema, CommentSchema, SiteSchema are your schema classes. $encoder = Encoder::instance([ // class names as strings '\Author' => '\AuthorSchema', // '::class' constant (PHP 5.5+) convenient for classes in namespaces Comment::class => CommentSchema::class, // Schema instances could be used as well Post::class => $postSchema, // callables are also supported Site::class => function (FactoryInterface $factory) use (...) { $schema = new SiteSchema($factory, ..., ..., ...); return $schema; } ]); ``` -------------------------------- ### Run Composer Tests Source: https://github.com/neomerx/json-api/wiki/Testing-and-Performance Executes the test suite defined in the project's composer.json file. This command typically relies on a testing framework configured for the project, such as PHPUnit. ```bash $ composer test ``` -------------------------------- ### CodecMatcher::findDecoder Renamed Source: https://github.com/neomerx/json-api/wiki/Upgrade-Notes The `findDecoder` method within the `CodecMatcherInterface` has been renamed to `matchDecoder`. This change is a minor API adjustment for consistency in naming conventions. ```APIDOC CodecMatcherInterface::findDecoder Renamed - Old Method Name: findDecoder - New Method Name: matchDecoder - Description: The method responsible for finding a decoder in `CodecMatcherInterface` has been renamed from `findDecoder` to `matchDecoder` for improved clarity and consistency. - Related Issue: https://github.com/neomerx/json-api/issues/112 ``` -------------------------------- ### JSON API Resource Updates (PATCH) Source: https://github.com/neomerx/json-api/blob/master/spec/current.txt Explains how to update an existing resource by sending a PATCH request. The URL for the resource can be found in its 'self' link or from a previous GET request. ```APIDOC PATCH /photos/1 HTTP/1.1 Content-Type: application/vnd.api+json Accept: application/vnd.api+json { "data": { "type": "photos", "id": "1", "attributes": { "title": "New Title" } } } ``` -------------------------------- ### Encode Data with JSON API Encoder Options Source: https://github.com/neomerx/json-api/wiki/Home Illustrates how to use the Encoder instance to encode data into JSON API format. This includes setting encoding options like pretty printing, adding top-level links and meta information, specifying included resource paths, and applying field sets for selective attribute inclusion. ```php use Neomerx\JsonApi\Encoder\Link; $isSubUrl = false; $hasMeta = false; $meta = ['key' => 'value']; $links = [ Link::FIRST => new Link($isSubUrl,'http://example.com/sites?first', $hasMeta), Link::LAST => new Link($isSubUrl,'http://example.com/sites?last', $hasMeta), Link::PREV => new Link($isSubUrl,'http://example.com/sites?prev', $hasMeta), Link::NEXT => new Link($isSubUrl,'http://example.com/sites?next', $hasMeta), ]; $result = $encoder ->withEncodeOptions(JSON_PRETTY_PRINT) ->withUrlPrefix('http://example.com') ->withLinks($links) ->withMeta($meta) ->withIncludedPaths([ 'posts', 'posts.author', 'posts.comments', ]) ->withFieldSets([ // Attributes and relationships that should be shown 'sites' => ['name', 'posts'], 'posts' => ['author'], 'people' => ['first_name'], ]) ->encodeData($site); // $site is the resource object to encode ``` -------------------------------- ### Dockerized Performance Tests (PHP Versions) Source: https://github.com/neomerx/json-api/blob/master/sample/README.md Runs performance tests using Docker Compose for different PHP versions (7.1, 7.2, 7.3, 7.4). These commands leverage Composer scripts to manage the Dockerized test environments. ```shell $ composer perf-test-php-7-1 ``` ```shell $ composer perf-test-php-7-2 ``` ```shell $ composer perf-test-php-7-3 ``` ```shell $ composer perf-test-php-7-4 ``` -------------------------------- ### JSON:API Relationship Deletion Example Source: https://github.com/neomerx/json-api/blob/master/spec/current.txt Demonstrates a DELETE request to remove comments from an article's relationship, adhering to JSON:API specifications. It includes the request body format and expected HTTP responses. ```APIDOC DELETE /articles/1/relationships/comments HTTP/1.1 Content-Type: application/vnd.api+json Accept: application/vnd.api+json { "data": [ { "type": "comments", "id": "12" }, { "type": "comments", "id": "13" } ] } Note: RFC 7231 specifies that a DELETE request may include a body, but that a server may reject the request. This spec defines the semantics of a server, and we are defining its semantics for JSON:API. Responses: 202 Accepted: If a relationship update request has been accepted for processing, but the processing has not been completed by the time the server responds, the server MUST return a 202 Accepted status code. 204 No Content: A server MUST return a 204 No Content status code if an update is successful and the representation of the resource in the request matches the result. This is the appropriate response to a POST request sent to a URL from a to-many relationship link when that relationship already exists. It is also the appropriate response to a DELETE request sent to a URL from a to-many relationship link when that relationship does not exist. 200 OK: If a server accepts an update but also changes the targeted relationship(s) in other ways than those specified by the request, it MUST return a 200 OK response. The response document MUST include a representation of the updated relationship(s). A server MUST return a 200 OK status code if an update is successful, the client’s current data remain up to date, and the server responds only with top-level meta data. In this case the server MUST NOT include a representation of the updated relationship(s). 403 Forbidden: A server MUST return 403 Forbidden in response to an unsupported request to update a relationship. Other Responses: A server MAY respond with other HTTP status codes. A server MAY include error details with error responses. A server MUST prepare responses, and a client MUST interpret responses, in accordance with HTTP semantics. ``` -------------------------------- ### JSON API HTTP Response Generation Source: https://github.com/neomerx/json-api/wiki/Parsing-API-Parameters Illustrates how to use the `BaseResponses` class to generate standard JSON API HTTP responses. This includes creating responses for newly created resources with appropriate status codes and headers. ```php // `Responses` should extend `Neomerx\JsonApi\Http\BaseResponses` $responses = new Responses(...); // response for newly created resource with // HTTP code 201 + 'location' header $response = $responses->getCreatedResponse($newAuthor); ``` -------------------------------- ### Parse HTTP Accept and Content-Type Headers Source: https://github.com/neomerx/json-api/wiki/Parsing-API-Parameters Shows how to parse HTTP `Accept` and `Content-Type` headers using `HeaderParametersParser`. It handles complex `Accept` header values and single `Content-Type` values according to RFC specifications. ```php use Neomerx\JsonApi\Contracts\Http\Headers\AcceptHeaderInterface; use Neomerx\JsonApi\Factories\Factory; use Neomerx\JsonApi\Http\Headers\AcceptHeader; $parser = new HeaderParametersParser(new Factory()); $acceptValue = 'foo/bar.baz;media=param;q=0.5;ext="ext1,ext2", type/*, */*'; foreach($parser->parseAcceptHeader($acceptValue) as $acceptMediaType) { ... } $contentTypeValue = 'application/vnd.api+json'; $contentMediaType = $parser->parseContentTypeHeader($contentTypeValue); ``` -------------------------------- ### PHP Schema: Show Identifiers in Relationships Source: https://github.com/neomerx/json-api/wiki/Schemas Illustrates how to represent a relationship using only the resource identifier when full resource data is not available or desired. This is useful for foreign keys, linking to related resources without embedding them. ```php 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'), ], ]; } } ``` -------------------------------- ### JSON:API Query Parameter Families Source: https://github.com/neomerx/json-api/blob/master/spec/current.txt Explains the concept of query parameter families in JSON:API, defining how parameters with bracketed notation (e.g., page[offset]) are grouped and named. It also covers implementation-specific parameter naming conventions. ```APIDOC Query Parameters: Query Parameter Families: Although “query parameter” is a common term in everyday web development, it is not a well-standardized concept. Therefore, JSON:API provides its own definition of a query parameter. For the most part, JSON:API’s definition coincides with colloquial usage, and its details can be safely ignored. However, one important consequence of this definition is that a URL like the following is considered to have two distinct query parameters: /?page[offset]=0&page[limit]=10 The two parameters are named page[offset] and page[limit]; there is no single page parameter. In practice, however, parameters like page[offset] and page[limit] are usually defined and processed together, and it’s convenient to refer to them collectively. Therefore, JSON:API introduces the concept of a query parameter family. A “query parameter family” is the set of all query parameters whose name starts with a “base name”, followed by zero or more instances of empty square brackets (i.e. []) or square-bracketed legal member names. The family is referred to by its base name. For example, the filter query parameter family includes parameters named: filter, filter[x], filter[], filter[x][], filter[][], filter[x][y], etc. However, filter[_] is not a valid parameter name in the family, because _ is not a valid member name. Implementation-Specific Query Parameters: Implementations MAY support custom query parameters. However, the names of these query parameters MUST come from a family whose base name is a legal member name and also contains at least one non a-z character (i.e., outside U+0061 to U+007A). It is RECOMMENDED that a capital letter (e.g. camelCasing) be used to satisfy the above requirement. If a server encounters a query parameter that does not follow the naming conventions above, and the server does not know how to process it as a query parameter from this specification, it MUST return 400 Bad Request. ``` -------------------------------- ### Neomerx JSON API Performance Tests Source: https://github.com/neomerx/json-api/blob/master/sample/README.md Runs performance tests for the Neomerx JSON API application. The default execution runs with standard parameters, while the timed execution allows measurement of execution time and specifies the number of iterations. ```shell $ php sample.php -t ``` ```shell $ time php sample.php -t=10000 ``` -------------------------------- ### PHP Custom Encoder Implementation Source: https://github.com/neomerx/json-api/wiki/Extending-Encoder Provides an example of extending the core Neomerx JSON:API classes (`Container`, `Factory`, `Encoder`) to implement custom logic. This includes overriding `getResourceType` in `YourContainer` and `createSchemaContainer` in `YourFactory` to achieve custom schema handling. ```PHP use Doctrine\Common\Util\ClassUtils; use Neomerx\JsonApi\Encoder\Encoder; use Neomerx\JsonApi\Schema\SchemaContainer; use Neomerx\JsonApi\Factories\Factory; class YourContainer extends SchemaContainer { protected function getResourceType($resource) { return ClassUtils::getRealClass(get_class($resource)); } } class YourFactory extends Factory { public function createSchemaContainer(iterable $schemas): SchemaContainerInterface { return new YourContainer($this, $schemas); } } class YourEncoder extends Encoder { protected static function createFactory(): FactoryInterface { return new YourFactory(); } } ``` -------------------------------- ### Compound Document Example Source: https://github.com/neomerx/json-api/blob/master/spec/current.txt Shows a JSON:API compound document containing primary data (an article) and included related resources (author and comments). This structure reduces the number of HTTP requests by embedding related resources directly in the response. ```JSON { "data": [{ "type": "articles", "id": "1", "attributes": { "title": "JSON:API paints my bikeshed!" }, "links": { "self": "http://example.com/articles/1" }, "relationships": { "author": { "links": { "self": "http://example.com/articles/1/relationships/author", "related": "http://example.com/articles/1/author" }, "data": { "type": "people", "id": "9" } }, "comments": { "links": { "self": "http://example.com/articles/1/relationships/comments", "related": "http://example.com/articles/1/comments" }, "data": [ { "type": "comments", "id": "5" }, { "type": "comments", "id": "12" } ] } } }], "included": [ { "type": "people", "id": "9", "attributes": { "name": "Jane Doe" } }, { "type": "comments", "id": "5", "attributes": { "body": "I like this article!" }, "relationships": { "author": { "data": { "type": "people", "id": "9" } } } }, { "type": "comments", "id": "12", "attributes": { "body": "This is great!" }, "relationships": { "author": { "data": { "type": "people", "id": "9" } } } } ] } ```