2017 © Pedro Peláez
 

library laravel-jsonapi-http

A package for Laravel projects supporting the JSON:API specification

image

tomblakemore/laravel-jsonapi-http

A package for Laravel projects supporting the JSON:API specification

  • Sunday, May 7, 2017
  • by tomblakemore
  • Repository
  • 1 Watchers
  • 0 Stars
  • 2 Installations
  • PHP
  • 0 Dependents
  • 0 Suggesters
  • 0 Forks
  • 0 Open issues
  • 7 Versions
  • 0 % Grown

The README.md

Laravel JSON:API HTTP package

Description

A package for Laravel projects supporting the JSON:API specification., (*1)

Features supported in the package:, (*2)

  • Relationships
  • Includes
  • Filtering
  • Pagination
  • Sorting

For full details of the JSON:API spec see http://jsonapi.org/format., (*3)

Installation using Composer

Use Composer to install this package. If you don't have Composer already installed, then install as per the documentation., (*4)

Inside your application folder run:, (*5)

composer require tomblakemore/laravel-jsonapi-http

Setup

Add the service provider to the config/app.php file., (*6)

'providers' => [
    ...

    JsonApiHttp\RequestServiceProvider::class
],

Add the following middleware groups to the app\Http\Kernel.php class., (*7)

protected $middlewareGroups = [
    ...

    'jsonapi' => [
        \JsonApiHttp\Middleware\SetRequest::class,
        \JsonApiHttp\Middleware\CheckAcceptHeaders::class,
        \JsonApiHttp\Middleware\CheckForContentTypeHeader::class,
        \JsonApiHttp\Middleware\VerifyContentTypeHeader::class,
        \JsonApiHttp\Middleware\VerifyContent::class,
        \JsonApiHttp\Middleware\SetResponseHeaders::class
    ],

    'relationships' => [
        \JsonApiHttp\Middleware\VerifyRelationship::class,
        \JsonApiHttp\Middleware\AddRelationshipToModel::class,
        \JsonApiHttp\Middleware\RemoveRelationshipFromModel::class
    ],

    'resources' => [
        \JsonApiHttp\Middleware\VerifyResource::class,
        \JsonApiHttp\Middleware\AddResourceAttributesToModel::class,
        \JsonApiHttp\Middleware\AddResourceRelationshipsToModel::class,
        \JsonApiHttp\Middleware\RemoveResourceRelationshipsFromModel::class
    ]
];

Basic usage

Below is a simple model and controller example for showing a list of people and fetching a specific person., (*8)

Create the people table., (*9)

php artisan make:migration create_people_table --create=people

Add the below to the migration file., (*10)

/**
 * Run the migrations.
 *
 * @return void
 */
public function up()
{
    Schema::create('people', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->timestamps();
    });
}

Create the Person model and fill in the property $type. The type is the JSON:API resource type and should be the plural representation of the model name, so in this case people., (*11)

<?php

namespace App;

use JsonApiHttp\AbstractModel;

class Person extends AbstractModel
{
    /**
     * The resource type.
     *
     * @var string
     */
    protected $type = 'people';
}

A controller with two actions to fetch people and a person., (*12)

<?php

namespace App\Http\Controllers;

use App\Person;

use JsonApiHttp\Controller;
use JsonApiHttp\Request;

class PersonController extends Controller
{
    /**
     * The resource type.
     *
     * @var string
     */
    protected $type = 'people';

    /**
     * Display a list of people.
     *
     * @param \JsonApiHttp\Request $request
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $query = Person::query();

        $request->filter($query)->sort($query);

        $people = $request->paginate($query, Person::perPage());
        $people->appends($request->query());

        $resources = $this->resources($request, $people);

        return response($resources);
    }

    /**
     * Display a person.
     *
     * @param \JsonApiHttp\Request $request
     * @param \App\Person $person
     * @return \Illuminate\Http\Response
     */
    public function show(Request $request, Person $person)
    {
        $resource = $this->resource($request, $person);
        return response($resource);
    }
}

Two routes to direct requests to the two controller actions., (*13)

Route::group(['middleware' => ['jsonapi', 'resources']], function () {
    Route::get('/people', 'PersonController@index')->name('people.index');
    Route::get('/people/{person}', 'PersonController@show')->name('people.show');
});

The resources are now accessible on the following endpoints:, (*14)

  • GET /people
  • GET /people/:id

Relationships

Objects can be represented by JSON:API relationship endpoints. We'll create a simple Patient > Doctor relationship as an example., (*15)

Create the doctors table., (*16)

php artisan make:migration create_doctors_table --create=doctors

Add the below to the migration file., (*17)

/**
 * Run the migrations.
 *
 * @return void
 */
public function up()
{
    Schema::create('doctors', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->timestamps();
    });
}

Create the Doctor model and patients relationship., (*18)

<?php

namespace App;

use JsonApiHttp\AbstractModel;

class Doctor extends AbstractModel
{
    /**
     * The resource type.
     *
     * @var string
     */
    protected $type = 'doctors';

    /**
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function patients()
    {
        return $this->hasMany(Patient::class);
    }

    /**
     * Return any the relations to display in the JSON:API output.
     *
     * @return array
     */
    public function relations()
    {
        return ['patients'];
    }
}

Create a controller for the relationships., (*19)

<?php

namespace App\Http\Controllers;

use App\Doctor;

use JsonApiHttp\RelationshipsController;
use JsonApiHttp\Request;

class DoctorRelationshipsController extends RelationshipsController
{
    /**
     * The resource type.
     *
     * @var string
     */
    protected $type = 'doctors';

    /**
     * Display a relation or collection of relations.
     *
     * @param \JsonApiHttp\Request $request
     * @param \App\Doctor $doctor
     * @param string $relation
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request, Doctor $doctor, $relation)
    {
        $relations = $this->relations($request, $doctor, $relation);
        return response($relations);
    }

    /**
     * Display a relationship.
     *
     * @param \JsonApiHttp\Request $request
     * @param \App\Doctor $doctor
     * @param string $relation
     * @return \Illuminate\Http\Response
     */
    public function show(Request $request, Doctor $doctor, $relation)
    {
        $relationship = $this->relationship($request, $doctor, $relation);
        return response($relationship);
    }
}

Create the patients table., (*20)

php artisan make:migration create_patients_table --create=patients

Add the below to the migration file., (*21)

/**
 * Run the migrations.
 *
 * @return void
 */
public function up()
{
    Schema::create('patients', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('doctor_id')->unsigned()->index();
        $table->foreign('doctor_id')->references('id')->on('doctors');
        $table->string('name');
        $table->timestamps();
    });
}

Create the Patient model and doctor relationship., (*22)

<?php

namespace App;

use JsonApiHttp\AbstractModel;

class Patient extends AbstractModel
{
    /**
     * The resource type.
     *
     * @var string
     */
    protected $type = 'patients';

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function doctor()
    {
        return $this->belongsTo(Doctor::class);
    }

    /**
     * Return any the relations to display in the JSON:API output.
     *
     * @return array
     */
    public function relations()
    {
        return ['doctor'];
    }
}

Create a controller for the relationships., (*23)

<?php

namespace App\Http\Controllers;

use App\Patient;

use JsonApiHttp\RelationshipsController;
use JsonApiHttp\Request;

class PatientRelationshipsController extends RelationshipsController
{
    /**
     * The resource type.
     *
     * @var string
     */
    protected $type = 'patients';

    /**
     * Display a relation or collection of relations.
     *
     * @param \JsonApiHttp\Request $request
     * @param \App\Patient $patient
     * @param string $relation
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request, Patient $patient, $relation)
    {
        $relations = $this->relations($request, $patient, $relation);
        return response($relations);
    }

    /**
     * Display a relationship.
     *
     * @param \JsonApiHttp\Request $request
     * @param \App\Patient $patient
     * @param string $relation
     * @return \Illuminate\Http\Response
     */
    public function show(Request $request, Patient $patient, $relation)
    {
        $relationship = $this->relationship($request, $patient, $relation);
        return response($relationship);
    }
}

Create routes to direct requests to two relationship controllers., (*24)

Route::group(['middleware' => ['jsonapi', 'relationships']], function () {

    Route::get(
        'doctors/{doctor}/{relation}',
        'DoctorRelationshipsController@index'
    )
    ->where('relation', 'patients')
    ->name('doctors.relations.index');

    Route::get(
        'doctors/{doctor}/relationships/{relation}',
        'DoctorRelationshipsController@show'
    )
    ->where('relation', 'patients')
    ->name('doctors.relations.show');

    Route::get(
        'patients/{patient}/{relation}',
        'PatientRelationshipsController@index'
    )
    ->where('relation', 'doctor')
    ->name('patients.relations.index');

    Route::get(
        'patients/{patient}/relationships/{relation}',
        'PatientRelationshipsController@show'
    )
    ->where('relation', 'doctor')
    ->name('patients.relations.show');

});

The relationships are now accessible on the following endpoints:, (*25)

  • GET /doctors/:id/patients
  • GET /doctors/:id/relationships/patients
  • GET /patients/:id/doctor
  • GET /patients/:id/relationships/doctor

Includes

To fetch the related objects in a single request use the ?include query parameter., (*26)

GET /patients/1?include=doctor

You can also use the dot notation to return the relations of relations., (*27)

GET /patients/1?include=doctor.patients

Filtering

To filter a result set pass a filter parameter in the query string., (*28)

The value can be a combination of comma separated values (AND) and/or pipe separated values (OR)., (*29)

Nesting of AND and OR operations can be achieved using parathesis., (*30)

The attribute and attribute/value pair to query on are joined by a colon character., (*31)

Operators supported include ! (not equal to), < <= => > <> (less and greater than operators including an alternative not equal to operator), ^ !^ (begins/does not begin with), $ !$ (ends/does not end with), ^$ !^$ (contains/does not contain)., (*32)

To filter by a single attribute (exact value)., (*33)

GET /patients?filter=name:tom

To filter by multiple values on a single attribute., (*34)

GET /patients?filter=name:(tom|ben)

Relationships can be queried with the value being one or more IDs of the related resources to query on. Both belongs to and has many type relationships are supported., (*35)

GET /patients?filter=doctor:1

Pagination

Use the page and perPage query parameters to control the paging of result sets., (*36)

GET /patients?page=1&perPage=10

Sorting

Use the sort query parameter to sort a result set. The value should be an attribute of the model. Prefix with - sign to sort descending. Multiple attributes can be specified, separated by a comma., (*37)

GET /patients?sort=-name

Tests

These will be added soon!, (*38)

The Versions

07/05 2017

dev-master

9999999-dev

A package for Laravel projects supporting the JSON:API specification

  Sources   Download

MIT

The Requires

  • php >=5.4.0

 

The Development Requires

by Tom Blakemore

07/05 2017

v1.3.2

1.3.2.0

A package for Laravel projects supporting the JSON:API specification

  Sources   Download

MIT

The Requires

  • php >=5.4.0

 

The Development Requires

by Tom Blakemore

31/03 2017

v1.3.1

1.3.1.0

A package for Laravel projects supporting the JSON:API specification

  Sources   Download

MIT

The Requires

  • php >=5.4.0

 

The Development Requires

by Tom Blakemore

29/03 2017

v1.3.0

1.3.0.0

A package for Laravel projects supporting the JSON:API specification

  Sources   Download

MIT

The Requires

  • php >=5.4.0

 

The Development Requires

by Tom Blakemore

24/03 2017

v1.2.0

1.2.0.0

A package for Laravel projects supporting the JSON:API specification

  Sources   Download

MIT

The Requires

  • php >=5.4.0

 

The Development Requires

by Tom Blakemore

24/03 2017

v1.1.0

1.1.0.0

A package for Laravel projects supporting the JSON:API specification

  Sources   Download

MIT

The Requires

  • php >=5.4.0

 

The Development Requires

by Tom Blakemore

24/03 2017

v1.0.0

1.0.0.0

A package for Laravel projects supporting the JSON:API specification

  Sources   Download

MIT

The Requires

  • php >=5.4.0

 

The Development Requires

by Tom Blakemore