undabot/json-api-symfony

Allow symfony apps to easy handle JSON API compatible requests and responses

Installs: 7 233

Dependents: 1

Suggesters: 0

Security: 0

Stars: 0

Watchers: 4

Forks: 0

Open Issues: 7

Type:symfony-bundle


README

pipeline status coverage report

"repositories": [
    {
      "type": "vcs",
      "url": "git@gitlab.com:undabot/json-api-symfony.git"
    }
  ],

Usage

Responder

First create a Responder class that extends AbstractResponder and implement getMap() method. getMap() method should return array of classes mapped to callable that will accept the class of an item you send to the Responder as a key, and a callable (annon. function, factory method reference, ...) that should convert that particular data object to an API model (i.e. the DTO).

<?php

declare(strict_types=1);

use Undabot\SymfonyJsonApi\Http\Service\Responder\AbstractResponder;

class CmsResponder extends AbstractResponder
{
    /**
     * @return array<string, callable>
     */
    public function getMap(): array
    {
        return [
            Entity::class => [EntityReadModel::class, 'fromEntity'],
        ];
    }
}

Once Responder has been created, it can be used this way

<?php

class Controller
{
    public function get(
        CmsResponder $responder
    ): ResourceCollectionResponse {
        ... # fetch array of entities

        return $responder->resourceCollection(
            $entities
        );
    }

Each method accepts a data object (or collection/array of data objects) along with some other optional arguments and constructs a DTO representing the JSON:API compliant response:

That response will then be encoded to the JSON:API compliant JSON Response by the \Undabot\SymfonyJsonApi\Http\EventSubscriber\ViewResponseSubscriber

resourceCollection(...) method

public function resourceCollection(
  array $primaryData, 
  array $includedData = null, 
  array $meta = null, 
  array $links = null
): ResourceCollectionResponse()

Accepts an array of entities (or any other data objects you have defined a encoding map entry for) and converts them to a ResourceCollectionResponse.

Configuration

Exception listener has default priority of -128 but it can be configured by creating config/packages/json_api_symfony.yaml with following parameters

json_api_symfony:
    exception_listener_priority: 100

Naming

Entity

Domain object that is modeled and used in the application. Has nothing to do with the outer world.

(API) Model

Domain representation for specific API. Data-transfer object, POPO that contains only values of attributes and identifiers of related resources.

(JSON:API) Resource

Object representation of JSON:API resource defined by the JSON:API specification.

Data conversion flow

Development

There is a custom docker image that can be used for development. This docker container should be used to run tests and check for any compatibility issues.

This repo is mounted inside of the container and any changes made to the files are automatically propagated into the container. There isnt any syncing, the filesystem is pointed to the 2 locations at the same time.

A script called dev.sh can be used to manage the image. Here are the avaliable commands:

  • ./dev.sh build

    used to build base dev docker image, and to install composer and dependencies at first run
    
  • ./dev.sh run

    starts the dev container
    
  • ./dev.sh stop

    stops the dev container
    
  • ./dev.sh ssh

    attaches the container shell to the terminal so that you can execute commands inside of the container
    
  • ./dev.sh test

    run php unit tests inside of the running container
    
  • ./dev.sh qc

    executes qc tests
    
  • ./dev.sh install executes composer install --optimize-autoloader