Un endpoint de relación, como /articles/1/relationships/author, devuelve solo el linkage de una relación (el type y el id del relacionado) y permite cambiarlo. Las rutas y los controladores los escribes tú; el paquete valida la forma del documento y arma la respuesta.
Todavía en validación. Las relaciones, included y los endpoints de relación están probados con una API de referencia completa dentro de las pruebas del paquete, que validan cada respuesta contra el esquema oficial de JSON:API. Aún no se han validado en una aplicación real. Si algo no te encaja, abre un issue.
Leer una relación
Una Relationship devuelta desde un controlador es la respuesta de un endpoint de relación: {jsonapi, links, data, meta} con solo el 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]),
);
}
Escribir una relación
Para escribir una relación, lee el linkage con RelationshipDocument: el paquete ya validó su forma (mira Leer el documento de entrada). Lo que depende de tu modelo lo revisas tú, con estos códigos:
| Situación | Estado | source. |
|---|---|---|
| Una lista donde va un solo identificador | 422 | /data |
El type no es el de la relación | 409 | /data/type |
| El recurso relacionado no existe | 404 | /data |
use MundoProgra\JsonApi\Exceptions\JsonApiException;
use MundoProgra\JsonApi\Http\Requests\RelationshipDocument;
public function updateAuthor(Request $request, string $article) {
$document = RelationshipDocument::of($request); // data() es null, un identificador o una lista; isList() dice cuál
if ($document->isList()) { // una lista donde va un identificador
throw JsonApiException::make(status: 422, detail: 'A to-one relationship takes one identifier or null.', pointer: '/data');
}
$identifier = $document->data(); // ['type' => 'authors', 'id' => '3'] o null
if ($identifier !== null && $identifier['type'] !== 'authors') {
throw JsonApiException::make(status: 409, pointer: '/data/type'); // el tipo no es el de la relación
}
$author = $identifier === null ? null : Author::find($identifier['id'])
?? throw JsonApiException::make(status: 404, pointer: '/data'); // el recurso no existe
// ... asociar, guardar y responder con la relación resultante (`200`)
}
Qué hace cada verbo
PATCHreemplaza la relación.POSTagrega elementos a una relación a muchos.DELETEquita elementos de una relación a muchos.
Revisa todo antes de escribir, para que un error no deje cambios a medias.
El ejemplo completo, con lecturas, escrituras y errores, está en tests/Fixtures/ReferenceApi. Los códigos de error están en Errores.