2017 © Pedro Peláez
 

library halapi

A PHP library to support implementing representations for HAL, REST over JSON web services

image

bigz/halapi

A PHP library to support implementing representations for HAL, REST over JSON web services

  • Monday, July 23, 2018
  • by bigz
  • Repository
  • 1 Watchers
  • 1 Stars
  • 75 Installations
  • PHP
  • 1 Dependents
  • 0 Suggesters
  • 0 Forks
  • 0 Open issues
  • 6 Versions
  • 295 % Grown

The README.md

Hypertext Application Language for (REpresentational State Transfer) Application Programming Interfaces

Build
Status Test Coverage SensioLabsInsight Scrutinizer Quality
Score Code Climate, (*1)

Given some conventions, displaying the HAL representation of any entity becomes very easy., (*2)

HAL is a json presentation format of the HATEOAS constraint, which is meant to add relations between objects., (*3)

It's whole specification is available here http://stateless.co/hal_specification.html, (*4)

The work is in progress to make it framework agnostic but actually relies on you using symfony/http-foundation, which will change in a close future to use psr6 (while providing a bridge) For the object manager, you are free to choose the one you like, although only doctrine orm has been implemented at the mement. Relation findings relies also a lot on doctrine's ClassMetadata interface, that we should maybe abstract (you can still use your own implementaion), (*5)

Usage

composer req bigz/halapi, (*6)

Symfony bundle

https://github.com/BigZ/HalapiBundle, (*7)

Full fledged example using symfony (a good starting point for your api)

https://github.com/BigZ/promote-api, (*8)

Example

use Halapi\AnnotationReader\AnnotationReaderInterface;
use Halapi\ObjectManager\ObjectManagerInterface;
use Halapi\UrlGenerator\UrlGeneratorInterface;
use Psr\Http\Message\ServerRequestInterface;

class EntityController()
{
    /**
     * You can provide your own implementations of those interfaces or use the provided ones.
     */
    public function __construct(
        UrlGeneratorInterface $router,
        AnnotationReaderInterface $annotationReader,
        ObjectManagerInterface $entityManager,
        PagerInterface $pager
    ) {
        $this->router = $router;
        $this->annotationReader = $annotationReader;
        $this->entityManager = $entityManager;
        $this->pager = $pager;
    }

    /**
     * Accessed by the /entities/{id} route
     */
    public function getHalFormattedEntity(ServerRequestInterface $request, Entity $entity)
    {
        $linksRelation = new LinksRelation(
            $this->annotationReader,
            $this->router,
            $this->entityManager,
        );
        $embeddedRelation = new EmbeddedRelation(
            $this->annotationReader,
            $request
        );

        $relationFactory = new RelationFactory([$linksRelation, $embeddedRelation]);
        $builder = new HALAPIBuilder($relationFactory);

        return $builder->gerSerializer()->serialize($entity);
    }

    /**
     * Accessed by the /entities
     */
    public function getHalFormattedCollection(ServerRequestInterface $request, $entityName)
    {
        $linksRelation = new LinksRelation(
            $this->router,
            $this->annotationReader,
            $this->entityManager,
            $request
        );
        $embeddedRelation = new EmbeddedRelation(
            $this->router,
            $this->annotationReader,
            $this->entityManager,
            $request
        );

        $relationFactory = new RelationFactory([$linksRelation, $embeddedRelation]);
        $builder = new HALAPIBuilder($relationFactory);

        $paginationFactory = new PaginationFactory(
            $this->router,
            $this->annotationReader,
            $this->entityManager,
            $this->pager
        );
        $paginatedRepresentation = $paginationFactory->getRepresentation($entityName);

        return $builder->gerSerializer()->serialize($paginatedRepresentation);
    }
}

Resources

List

Pagination

A list will give you a paginated ressource, HAL formatted., (*9)

/entities?limit=2&page=2, (*10)

Filtering

You can filter out results on specific fields., (*11)

/entities?filter[id]=5&filteroperator[id]=>, (*12)

Available operators are >, <, >=, <=, =, != Default operator is =, (*13)

Sorting

You can sort the result by any property, (*14)

/entities?sort=-created,title, (*15)

Entity

Creating new entities

POST /entities, (*16)

{ "entity": { "name": "eminem", "slug": "eminem", "bio": "rapper from detroit", "labels": [1, 2] } }, (*17)

will return, (*18)

{ "id": 2, "name": "eminem", "slug": "eminem", "bio": "rapper from detroit", "_links": { "self": "/artists/2", "labels": [ "/labels/1", "/labels/2" ] } }, (*19)

PUT & PATCH works the same way, (*20)

Embedding

By default, relations are not embeded. You can change this behaviour by specifiying wich embedeed entities you need. /entities/1?embed[]=gigs&embed[]=labels, (*21)

To allow an relation to be embedded, you must add an @Embeddable Annotation to your entity property., (*22)

use Halapi\Annotation\Embeddable;

/**
* The Embeddable annoation below is here if you want a custom route for your entity.
* By default, the generator would you "get_'entity's" which is the default behaviour
* of FOSRestBundle.
* @Embeddable("fetch_artists")
*/
class Artist
{
    /**
     * @var int
     *
     * @Expose
     */
    private $id;

    /**
     * @var Labels[]
     *
     * @Embeddable
     */
    protected $labels;
}

Roadmap to production readyness

  • (MUST) Improve coverage
  • (MUST) Implement sparse fieldset
  • (MUST) Implement deep resource inclusion
  • (SHOULD) support IN filter operator
  • (SHOULD) Refactor using propertyinfo component
  • (SHOULD) USE doctrine/reflection instead of doctrine/common
  • (SHOULD) Be able to serialize to any other hateoas format. Not so easy with jms...

The Versions

23/07 2018
26/11 2016

dev-scrutinizer-patch-1

dev-scrutinizer-patch-1

A PHP library to support implementing representations for HAL, REST over JSON web services

  Sources   Download

MIT

The Requires

 

The Development Requires

by Romain Richard