A Lightweight {JSON:API} Resource for Laravel.
composer require ark4ne/laravel-json-apiThis package is an specialisation of Laravel's JsonResource class. All the underlying API's are still there, thus in your controller you can still interact with JsonApiResource classes as you would with the base JsonResource class
Implementable methods :
protected function toType(Request $request): string; protected function toIdentifier(Request $request): int|string; protected function toAttributes(Request $request): iterable; protected function toRelationships(Request $request): iterable; protected function toResourceMeta(Request $request): ?iterable; protected function toMeta(Request $request): ?iterable;Example:
use Ark4ne\JsonApi\Resource\JsonApiCollection; use Ark4ne\JsonApi\Resource\JsonApiResource; use DateTimeInterface; use Illuminate\Http\Request; class UserResource extends JsonApiResource { protected function toAttributes(Request $request): iterable { return [ 'name' => $this->name, 'email' => $this->email, ]; } protected function toResourceMeta(Request $request): ?iterable { return [ 'created_at' => $this->created_at->format(DateTimeInterface::ATOM), 'updated_at' => $this->updated_at->format(DateTimeInterface::ATOM), ]; } protected function toRelationships(Request $request): iterable { return [ 'posts' => PostResource::relationship(fn() => $this->posts, fn() => [ 'self' => "https://api.example.com/user/{$this->id}/relationships/posts", 'related' => "https://api.example.com/user/{$this->id}/posts", ]), 'comments' => CommentResource::relationship(fn() => $this->whenLoaded('comments')), ]; } }Returns resource type.
protected function toType(Request $request): string { return 'user'; }Default returns model class in kebab case : App\Models\MyPost => my-post
@see {json:api} resource-identifier
Returns resource identifier.
protected function toIdentifier(Request $request): int|string { return $this->id; }Default returns model id.
@see {json:api} resource-attributes
Returns resource attributes.
protected function toAttributes(Request $request): iterable { return [ 'name' => $this->name, 'email' => $this->email, ]; }@see laravel: eloquent-conditional-attributes
Support laravel conditional attributes.
protected function toAttributes(Request $request): array { return [ 'name' => $this->name, 'email' => $this->email, // with lazy evaluation 'hash64' => fn() => base64_encode("{$this->id}-{$this->email}"), // Conditional attribute 'secret' => $this->when($request->user()->isAdmin(), 'secret-value'), // Merging Conditional Attributes $this->mergeWhen($request->user()->isAdmin(), [ 'first-secret' => 'value', 'second-secret' => 'value', ]), ]; }@see {json:api} resources-relationships
Returns resource relationships.
protected function toRelationships(Request $request): array { return [ 'avatar' => AvatarResource::relationship($this->avatar), // as collection, with condition 'comments' => CommentResource::relationship(fn() => $this->whenLoaded('comments'))->asCollection(), // with relationship (allow to include links and meta on relation) 'posts' => PostResource::relationship(fn() => $this->posts)->withLinks(fn() => [ 'self' => "https://api.example.com/user/{$this->id}/relationships/posts", 'related' => "https://api.example.com/user/{$this->id}/posts", ])->asCollection(), ]; }toRelationships must returns an array, keyed by string, of JsonApiResource or JsonApiCollection.
@see laravel: eloquent-conditional-relationships
Support laravel conditional relationships.
protected function toRelationships(Request $request): array { return [ 'avatar' => AvatarResource::relationship($this->avatar), // as collection, with condition 'comments' => CommentResource::relationship(fn() => $this->whenLoaded('comments'))->asCollection(), // with relationship (allow to include links and meta on relation) 'posts' => PostResource::relationship(fn() => $this->posts)->asCollection(), ]; }@see {json:api}: relation-linkage
@see {json:api}: relation-meta
Returns links and meta for a relation.
protected function toRelationships(Request $request): array { return [ 'posts' => PostResource::relationship(fn() => $this->posts)->withLinks(fn() => [ // links 'self' => "https://api.example.com/user/{$this->id}/relationships/posts", 'related' => "https://api.example.com/user/{$this->id}/posts", ])->withMeta(fn() => [ // meta 'creator' => $this->name, ]) ->asCollection(), ]; }@see {json:api}: resource-linkage
Returns resource links.
protected function toLinks(Request $request): ?array { return [ 'self' => route('api.user.show', ['id' => $this->id]), ]; }@see {json:api}: resource-meta
@see {json:api}: document-meta
Returns resource meta.
protected function toResourceMeta(Request $request): ?iterable { return [ 'created_at' => $this->created_at->format(DateTimeInterface::ATOM), 'updated_at' => $this->updated_at->format(DateTimeInterface::ATOM), ]; }@see {json:api}: document-meta
Returns document meta.
protected function toMeta(Request $request): ?iterable { return [ "copyright": "Copyright 2022 My Awesome Api", ]; }@see laravel: resource-collection
Collection are implemented in JsonApiCollection.
Usage is the same as laravel collections.
UserResource::collection(User::all()); // => JsonApiCollection