Integrate JSON:API resources on Laravel.
- 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_idorpost_id. - Own testing utilities built-in Laravel's ones to make integration tests easier.
You can install the package via composer:
composer require skore-labs/laravel-json-api
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
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()
);
}
}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.
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);public function testGetPostApi()
{
$this->get('/posts/1')->assertJsonApi(function (Assert $json) {
$json->hasId(1)
->hasType('post')
->hasAttribute('title', 'My summer vacation');
});
}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!
- Ruben Robles (@d8vjork)
- Skore (https://www.getskore.com/)
- And all the contributors
