Skip to content
MundoProgra JSON:API
Menu

Guide

Relationship endpoints

A relationship endpoint, such as /articles/1/relationships/author, returns only the linkage of a relationship (the type and id of the related one) and lets you change it. You write the routes and the controllers; the package validates the shape of the document and builds the response.

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.

Reading a relationship

A Relationship returned from a controller is the response of a relationship endpoint: {jsonapi, links, data, meta} with only the linkage.

public function author(string $article) {
  $model = Article::query()->with('author')->findOrFail($article);

  return Relationship::one($model->author, AuthorResource::class)->links(
    self: route('articles.relationships.author', [$model]),
    related: route('articles.author', [$model]),
  );
}

Writing a relationship

To write a relationship, read the linkage with RelationshipDocument: the package has already validated its shape (see Reading the input document). What depends on your model you check yourself, with these codes:

SituationStatussource.pointer
A list where a single identifier goes422/data
The type is not the one of the relationship409/data/type
The related resource does not exist404/data
use MundoProgra\JsonApi\Exceptions\JsonApiException;
use MundoProgra\JsonApi\Http\Requests\RelationshipDocument;

public function updateAuthor(Request $request, string $article) {
  $document = RelationshipDocument::of($request);        // data() is null, an identifier or a list; isList() says which

  if ($document->isList()) {                             // a list where an identifier goes
    throw JsonApiException::make(status: 422, detail: 'A to-one relationship takes one identifier or null.', pointer: '/data');
  }

  $identifier = $document->data();                       // ['type' => 'authors', 'id' => '3'] or null

  if ($identifier !== null && $identifier['type'] !== 'authors') {
    throw JsonApiException::make(status: 409, pointer: '/data/type');          // the type is not the relationship's
  }

  $author = $identifier === null ? null : Author::find($identifier['id'])
    ?? throw JsonApiException::make(status: 404, pointer: '/data');            // the resource does not exist

  // ... associate, save and answer with the resulting relationship (`200`)
}

What each verb does

  • PATCH replaces the relationship.
  • POST adds elements to a to-many relationship.
  • DELETE removes elements from a to-many relationship.

Check everything before writing, so an error does not leave half-made changes.

The complete example, with reads, writes and errors, is in tests/Fixtures/ReferenceApi. The error codes are in Errors.