api-skeletons/laravel-hal

Hypertext Application Language for Laravel
5,036 5
Install
composer require api-skeletons/laravel-hal
Latest Version:5.0.2
PHP:^8.0
License:MIT
Last Updated:Nov 18, 2023
Links: GitHub  ·  Packagist
Maintainer: tom_anderson

Hypertext Application Language for Laravel

Build Status Code Coverage Documentation Status PHP Version Laravel Version Total Downloads License

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",
      }
    ]
  }
}

Related Packages

gabrieloliverio/laravel5-generators

Database metadata-based generators for Laravel 5

1
erirk/paypalpayment

laravel-paypalpayment is simple package help you process direct credit card paym...

0
doctrine/dbal

Powerful PHP database abstraction layer (DBAL) with many features for database s...

631,580,251 9,707
laravel/framework

The Laravel Framework.

576,155,700 34,907
laravel/tinker

Powerful REPL for the Laravel framework.

489,754,436 7,444