Laravel cookbook · Beginner
Shape JSON responses with API Resources
Returning models directly leaks columns and makes response formats drift.
Approach
Define an API Resource per model that lists exactly which fields are returned, includes relations only when they were eager loaded, and adds conditional fields for privileged users.
Solution
<?php
// app/Http/Resources/OrderResource.php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class OrderResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'status' => $this->status->value,
'total' => $this->total_cents / 100,
'placed_at' => $this->created_at->toIso8601String(),
'customer' => new CustomerResource($this->whenLoaded('customer')),
'lines' => OrderLineResource::collection($this->whenLoaded('lines')),
'line_count' => $this->whenCounted('lines'),
'internal_notes' => $this->when($request->user()?->isAdmin(), $this->internal_notes),
];
}
}
<?php
// in a controller
use App\Http\Resources\OrderResource;
use App\Models\Order;
return OrderResource::collection(
Order::with('customer')->withCount('lines')->latest()->paginate(25)
);
Pitfalls
- Accessing relations in resources without eager loading, causing N+1 queries.
- Returning
$model->toArray()and relying on$hidden, which is easy to forget for new columns. - Changing field names in place; version the API or add new fields alongside old ones.
Variations
OrderResource::collection($paginator)includes paginationlinksandmetaautomatically.- Use
#[UseResource(OrderResource::class)]on the model to call$order->toResource().
Further reading: Eloquent API Resources
Reference: https://laravel.com/docs/13.x/eloquent-resources
More Laravel recipes
- Authorize actions with policies
- Cache expensive data with stale-while-revalidate
- Call external APIs with timeouts, retries and fakes
- Catch N+1 queries with strict Eloquent mode
- Delete old records automatically with prunable models
- Dispatch events and listeners after the transaction commits
- Issue scoped API tokens with Sanctum
- Make queued jobs reliable with retries, backoff and uniqueness