Skip to content
This repository was archived by the owner on Feb 14, 2023. It is now read-only.

skore/laravel-json-api

Repository files navigation

json-api-logo

Laravel JSON:API

latest tag packagist version run-tests phpstan StyleCI Codacy Badge Codacy Badge Scc Count Badge Scc Count Badge Take a peek on VSCode online

Integrate JSON:API resources on Laravel.

Features

  • Compatible and tested with all the Laravel LTS supported versions (see them here)
  • Full formatting using pure built-in model methods and properties.
  • Relationships and nested working with eager loading.
  • Permissions "out-of-the-box" authorising each resource view or list of resources.
  • Auto-hide not allowed attributes from responses like user_id or post_id.
  • Own testing utilities built-in Laravel's ones to make integration tests easier.

Installation

You can install the package via composer:

composer require skore-labs/laravel-json-api

Extra steps (important notice)

Although the package doesn't require anything else to make it work, is recommended to use a package like spatie/laravel-query-builder.

Though for some limitations (they removed the ability to append attributes), you should check this fork we did and maintain: skorelabs/laravel-query-builder

Usage

As simple as importing the class SkoreLabs\JsonApi\Http\Resources\JsonApiCollection for collections or SkoreLabs\JsonApi\Http\Resources\JsonApiResource for resources.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use SkoreLabs\JsonApi\Http\Resources\JsonApiCollection;
use App\User;

class UserController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        return new JsonApiCollection(
            User::all()
        );
    }
}

Custom resource type

To customise the resource type of a model you should do like this:

<?php

namespace SkoreLabs\JsonApi\Tests\Fixtures;

use Illuminate\Database\Eloquent\Model;
use SkoreLabs\JsonApi\Contracts\JsonApiable;

class Post extends Model implements JsonApiable
{
    /**
     * Get a custom resource type for JSON:API formatting.
     * 
     * @return string 
     */
    public function resourceType(): string
    {
        return 'custom-post';
    }
}

Note: Just remember to check the allowed types in the oficial JSON:API spec.

Authorisation

For authorize a resource or collection you'll need the view and viewAny on the model policy, which you can create passing the model to the make command:

php artisan make:policy UserPolicy -m User

Alternatively, you can pass an authorisation (boolean) to the constructor of the resource like this:

// Forced to allow view the user
return new JsonApiResource($user, true);

Testing

public function testGetPostApi()
{
    $this->get('/posts/1')->assertJsonApi(function (Assert $json) {
        $json->hasId(1)
            ->hasType('post')
            ->hasAttribute('title', 'My summer vacation');
    });
}

Collections

In case of a test that receives a JSON:API collection as a response, the first item will be the defaulted on all the methods that tests attributes and relationships.

In case you want to access a specific item you have the at method:

public function testGetPostsListApi()
{
    $this->get('/posts')->assertJsonApi(function (Assert $json) {
        // We're testing the first post here!
        $json->hasId(1)
            ->hasType('post')
            ->hasAttribute('title', 'My summer vacation @ Italy');

        // Now we want to test the second post of the collection
        $json->at(1)
            ->hasId(2)
            ->hasType('post')
            ->hasAttribute('title', 'What is really great for your diet');
    });
}

Note: Remember that this method takes in mind the array keys, so the first item is at 0, not 1!

Credits

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages