← All writing

Use API resources to keep response fields deliberate

Laravel 13 / PHP 8.3+Sources checked 2026-09-14

Returning a model directly is convenient until a new database column appears in the JSON response. An API resource gives the public contract an explicit place to live rather than inheriting every storage decision.

Select fields for the caller

public function toArray($request): array
{
    return [
        'id' => (string) $this->id,
        'name' => $this->name,
        'created_at' => $this->created_at?->toISOString(),
    ];
}

This method belongs inside a JsonResource subclass. The string ID is an intentional example contract; keep whatever representation your clients already rely on unless you version a change. Do not expose internal notes, tokens, or tenant-control fields just because they exist on the model.

Conditional relationships need query planning

Use conditional relationship inclusion where appropriate and eager-load only the relationships required by the endpoint. A resource that accesses an unloaded relationship for every item can create an N+1 query problem.

Resources format data; they do not replace policies or query scoping. The controller still needs to retrieve only records the current actor may access.

Test the exact allowed fields and assert sensitive fields are absent. Include null dates and missing optional relationships. A test that only asserts the response contains an ID may overlook accidental additions. When storage changes, the resource should help you decide whether the public API changes too, rather than letting the database migration silently make that decision for every client.

Reference

Official documentation.