A resource says what is shown of a model; a collection is a list of resources; a relationship links a resource with others. This page summarizes how to write each thing and what the package does with them.
If you have not written your first resource yet, start with Getting started.
What you write for each thing
| You want | You write |
|---|---|
| A resource | ArticleResource::make($article) |
| A collection | ArticleResource::collection($articles) (an array, a collection or a length-aware paginator) |
| A paginated collection | ArticleResource::collection(Article::query()->jsonApiPaginate()) |
Your own links or meta | jsonApiLinks($request) and jsonApiMeta($request) in the resource, or ->additional([...]) |
| A to-one or to-many relationship | Relationship::one($model, Class::class) / Relationship::many($models, Class::class) |
| A relationship without loading it | Relationship::unloaded()->links(...$this->relationshipLinks($request, 'author')) |
| The empty related resource | AuthorResource::make(null), which answers data: null |
Collections and pagination
- An empty collection is
data: []. - Pagination adds
links(first,last,prev,next) andmeta.page(currentPage,perPage,lastPage,total). Those links keepsort,filter,includeandfieldsexactly as the client sent them. The names inmeta.pagefollow the naming style: withkebabthey come out ascurrent-page,per-page,last-pageandtotal. - A simple or cursor paginator is not accepted, because it does not know how many pages there are, and throws a clear error.
The page size, its limit and what happens when the client goes over it are in Configuration.
Relationships
Still under validation. Relationships, included and relationship endpoints are tested with a complete reference API inside the package tests, which validate every response against the official JSON:API schema. They have not been validated in a real application yet. If something does not fit, open an issue.
Inside the resource, Relationship::one() and Relationship::many() build a relationship with its resource linkage (the type and id of the related one). A relationship that is not loaded does not come out, so the package never fires a query to complete a document.
relationshipLinks($request, 'author') builds {self}/relationships/author and {self}/author from the resource's own links.self. It is optional. You write the routes those links point to; see Relationship endpoints.
Included resources (included)
In included only what the client asked for with include comes out, and only from relationships that are already loaded and that the resource shows:
- Each resource appears once, identified by its
typeandid, and never repeats those already indata. - What a
fields[type]hides is not included either, so the document keeps the specification's full linkage.
The package does not load relationships for you when it builds the document. To load them without extra queries (the N+1 problem), use jsonApiInclude([...]) in your controller, as in Getting started. An include on a relationship that was not loaded is silently ignored.
Sparse fieldsets (fields)
fields[articles]=title trims the attributes and relationships of that type. The type, id, links and meta always stay. The query parameters, with their whitelists, are explained in Query parameters.