api-skeletons / laravel-hal
Hypertext Application Language for Laravel
Installs: 3 313
Dependents: 1
Suggesters: 0
Security: 0
Stars: 4
Watchers: 3
Forks: 1
Open Issues: 2
Requires
- php: ^8.0
- kylekatarnls/update-helper: ^1.2.1
- laravel/framework: ^8.0 || ^9.0
- nesbot/carbon: ^2.30
Requires (Dev)
- doctrine/coding-standard: ^8.2
- php-coveralls/php-coveralls: ^2.4
- phpunit/phpunit: ^9.5
- vimeo/psalm: ^4.18
README
HAL - Hypertext Application Language is a JSON dialect which gives a consistent and easy way to add HATEOAS - Hypertext As The Engine Of Application State - to your API. This library makes composing HAL responses easy including embedded data.
This library consists of a Hydrator Manager and you will write hydrators for the classes you want to serve as HAL. Central to this library is a Resource object on which HAL resources are attached.
Although this library is for Laravel, it is not specific to Eloquent. This same library can be used with any datasource to compose a HAL response.
This is a direct implementation of https://tools.ietf.org/html/draft-kelly-json-hal-08
Read The Documentation
Quick Look
return $this->hydratorManager->resource($data) ->addLink('self', route('routeName::fetch', $class->id)) ->addEmbeddedResource('example', $class->example) ->toArray();
Quick Start
- Create a hydrator manager
- Create a hydrator for the User class
- Create a hydrator for the Role class
- Compose these into a HAL resource and return HAL from a controller action
Create a hydrator manager
namespace App\HAL; use ApiSkeletons\Laravel\HAL\HydratorManager as HALHydratorManager; final class HydratorManager extends HALHydratorManager { public function __construct() { $this->classHydrators = [ \App\Models\Role::class => \App\HAL\Hydrator\RoleHydrator::class, \App\Models\User::class => \App\HAL\Hydrator\UserHydrator::class, ]; }
Create a hydrator for the User class
namespace App\HAL\Hydrator; use ApiSkeletons\Laravel\HAL\Hydrator; use ApiSkeletons\Laravel\HAL\Resource; use App\Models\User; final class UserHydrator extends Hydrator { public function extract($class): Resource { $data = []; $fields = [ 'id', 'name', 'email', ]; // Extract fields into an array to be used by the resource foreach ($fields as $field) { $data[$field] = $class->$field; } // Create a new resource and assign self link and extract the // roles into an embedded resource. Note `addEmbeddedResources` // is used for arrays and `addEmbeddedResource` is used for classes return $this->hydratorManager->resource($data) ->addLink('self', route('hal/user::fetch', $class->id)) ->addEmbeddedResources('roles', $class->roles) ; } }
Create a hydrator for the Role class
namespace App\HAL\Hydrator; use ApiSkeletons\Laravel\HAL\Hydrator; use ApiSkeletons\Laravel\HAL\Resource; use App\Models\Role; final class RoleHydrator extends Hydrator { public function extract($class): Resource { $data = []; $fields = [ 'id', 'name', 'guard_name', ]; // Extract fields into an array to be used by the resource foreach ($fields as $field) { $data[$field] = $class->$field; } // Create a new resource and assign self link and extract the // roles into an embedded resource. Note `addEmbeddedResources` // is used for arrays and `addEmbeddedResource` is used for classes return $this->hydratorManager->resource($data) ->addLink('self', route('hal/role::fetch', $class->id)) ; } }
Compose these into a HAL resource and return HAL from a controller action
public function fetch(User $user, Request $request) { $hydratorManager = new \App\HAL\HydratorManager(); return $hydratorManager->extract($user)->toArray(); }
HAL Response
{ "_links":{ "self":{ "href":"https://apiskeletons.com/user/1" } }, "id":1, "name":"Tom H Anderson", "email":"tom.h.anderson@gmail.com", "_embedded":{ "roles":[ { "_links":{ "self":{ "href":"https://apiskeletons.com/role/1" } }, "id":1, "name":"admin", "guard_name":"web", } ] } }