Laravel API Development
Agent Workflow (MANDATORY)
Before ANY implementation, spawn 3 agents in parallel, one Agent call each with a name:
- fuse-ai-pilot:explore-codebase - Analyze existing API patterns
- fuse-ai-pilot:research-expert - Verify Laravel API docs via Context7
- mcp__context7__query-docs - Check API Resources and Sanctum patterns
After implementation, run fuse-ai-pilot:sniper for validation.
Overview
Build RESTful APIs with Laravel using API Resources for response transformation and Sanctum for authentication.
| Component |
Purpose |
| Controllers |
Handle requests, delegate to services |
| Form Requests |
Validate input, authorize actions |
| API Resources |
Transform models to JSON |
| Middleware |
Auth, rate limiting, CORS |
| Routes |
Versioned endpoints with groups |
| Pagination |
Offset/cursor pagination |
| HTTP Client |
Consume external APIs |
Critical Rules
- Always use API Resources - Never return Eloquent models directly
- Versioned routes - Prefix with
/v1/, /v2/
- Validate all input - Use Form Requests, not inline validation
- Rate limiting - Configure per-route limits
- Consistent responses - Same structure, proper status codes
- Use services - Keep controllers thin
- Eager load - Prevent N+1 with
with() before pagination
Reference Guide
Core Concepts
| Topic |
Reference |
When to consult |
| Routing |
routing.md |
Defining versioned API routes |
| Controllers |
controllers.md |
Controller patterns, resource methods |
| Middleware |
middleware.md |
Route protection, request filtering |
| Validation |
validation.md |
Form Requests, validation rules |
Request/Response
| Topic |
Reference |
When to consult |
| Requests |
requests.md |
Accessing input, files, headers |
| Responses |
responses.md |
API Resources, status codes |
| Pagination |
pagination.md |
Offset/cursor pagination |
Advanced
| Topic |
Reference |
When to consult |
| Rate Limiting |
rate-limiting.md |
Throttle configuration |
| HTTP Client |
http-client.md |
Consuming external APIs |
| URLs |
urls.md |
URL generation, signed URLs |
| Strings |
strings.md |
String helpers, UUIDs, slugs |
| Redirects |
redirects.md |
Redirect responses |
Templates (Code Examples)
Controllers & Routes
| Template |
Purpose |
| ApiController.php.md |
Complete CRUD controller with service |
| api-routes.md |
Versioned routes with middleware |
| routing-examples.md |
Detailed routing patterns |
Validation & Resources
| Template |
Purpose |
| FormRequest.php.md |
Store/Update Form Requests |
| validation-rules.md |
All validation rules reference |
| ApiResource.php.md |
Resource with relationships |
External APIs
| Template |
Purpose |
| HttpClientService.php.md |
Reusable HTTP client service |
Quick Reference
Resource Response
return PostResource::collection($posts);
return PostResource::make($post);
Status Codes
return PostResource::make($post)->response()->setStatusCode(201);
return response()->json(null, 204);
Form Request
public function store(StorePostRequest $request): JsonResponse
{
$post = $this->service->create($request->validated());
return PostResource::make($post)->response()->setStatusCode(201);
}
Rate Limiting
Route::middleware('throttle:60,1')->group(fn () => ...);
Versioned Routes
Route::prefix('v1')->group(function () {
Route::apiResource('posts', PostController::class);
});
Pagination
return PostResource::collection(Post::paginate(15));
Feature Matrix
| Feature |
Status |
Reference |
| RESTful Controllers |
✅ |
controllers.md |
| API Resources |
✅ |
responses.md |
| Form Request Validation |
✅ |
validation.md |
| Route Versioning |
✅ |
routing.md |
| Route Model Binding |
✅ |
routing.md |
| Middleware |
✅ |
middleware.md |
| Rate Limiting |
✅ |
rate-limiting.md |
| Pagination |
✅ |
pagination.md |
| Cursor Pagination |
✅ |
pagination.md |
| HTTP Client |
✅ |
http-client.md |
| Signed URLs |
✅ |
urls.md |
| JSON Responses |
✅ |
responses.md |
Laravel 13 Notes
Attributes pour API Resources
Laravel 13 introduit #[Collects] et #[PreserveKeys] pour configurer les ResourceCollections via attributs PHP.
use Illuminate\Http\Resources\Json\ResourceCollection;
use Illuminate\Http\Resources\Attributes\Collects;
use Illuminate\Http\Resources\Attributes\PreserveKeys;
#[Collects(PostResource::class)]
#[PreserveKeys]
final class PostCollection extends ResourceCollection {}
JSON:API compliance
Pour les APIs JSON:API (sparse fieldsets, inclusion, links), voir [[laravel-jsonapi]] qui couvre ?include=, ?fields[type]=, et la pagination conforme spec.
Best Practices
DO
- Utiliser API Resources (
JsonResource) pour toute réponse JSON publique
- Versionner via URL (
/api/v1) plutôt que via header (lisible, cacheable)
- Rate-limiter par utilisateur ET par IP (
throttle:60,1 + custom limiter)
- Documenter via OpenAPI/Scribe avant de coder l'endpoint
- Préférer
cursor() pagination pour grandes listes (stable, performant)
DON'T
- Retourner directement un Model Eloquent (fuite de colonnes sensibles)
- Mélanger statuts HTTP (toujours 422 pour validation, 401 vs 403)
- Skip Form Request validation (jamais valider en controller)
- Exposer les IDs auto-increment publiquement (préférer UUID/ULID)
- Oublier
PreventRequestForgery exemption pour les webhooks externes
1---2name: laravel-api3description: Use when creating API endpoints, transforming responses with API Resources, or handling API authentication, rate limiting, or versioning.4---56<objective>7Covers building RESTful APIs with Laravel: API Resources for response8transformation, Sanctum authentication, rate limiting, route versioning, Form9Request validation, pagination (offset/cursor), and consuming external APIs10via the HTTP client. For JSON:API-spec-compliant endpoints (sparse fieldsets,11inclusion, links), see laravel-jsonapi instead.12</objective>1314# Laravel API Development1516## Agent Workflow (MANDATORY)1718Before ANY implementation, spawn 3 agents in parallel, one `Agent` call each with a `name`:19201. **fuse-ai-pilot:explore-codebase** - Analyze existing API patterns212. **fuse-ai-pilot:research-expert** - Verify Laravel API docs via Context7223. **mcp__context7__query-docs** - Check API Resources and Sanctum patterns2324After implementation, run **fuse-ai-pilot:sniper** for validation.2526---2728## Overview2930Build RESTful APIs with Laravel using API Resources for response transformation and Sanctum for authentication.3132| Component | Purpose |33|-----------|---------|34| **Controllers** | Handle requests, delegate to services |35| **Form Requests** | Validate input, authorize actions |36| **API Resources** | Transform models to JSON |37| **Middleware** | Auth, rate limiting, CORS |38| **Routes** | Versioned endpoints with groups |39| **Pagination** | Offset/cursor pagination |40| **HTTP Client** | Consume external APIs |4142---4344## Critical Rules45461. **Always use API Resources** - Never return Eloquent models directly472. **Versioned routes** - Prefix with `/v1/`, `/v2/`483. **Validate all input** - Use Form Requests, not inline validation494. **Rate limiting** - Configure per-route limits505. **Consistent responses** - Same structure, proper status codes516. **Use services** - Keep controllers thin527. **Eager load** - Prevent N+1 with `with()` before pagination5354---5556## Reference Guide5758### Core Concepts5960| Topic | Reference | When to consult |61|-------|-----------|-----------------|62| **Routing** | [routing.md](references/routing.md) | Defining versioned API routes |63| **Controllers** | [controllers.md](references/controllers.md) | Controller patterns, resource methods |64| **Middleware** | [middleware.md](references/middleware.md) | Route protection, request filtering |65| **Validation** | [validation.md](references/validation.md) | Form Requests, validation rules |6667### Request/Response6869| Topic | Reference | When to consult |70|-------|-----------|-----------------|71| **Requests** | [requests.md](references/requests.md) | Accessing input, files, headers |72| **Responses** | [responses.md](references/responses.md) | API Resources, status codes |73| **Pagination** | [pagination.md](references/pagination.md) | Offset/cursor pagination |7475### Advanced7677| Topic | Reference | When to consult |78|-------|-----------|-----------------|79| **Rate Limiting** | [rate-limiting.md](references/rate-limiting.md) | Throttle configuration |80| **HTTP Client** | [http-client.md](references/http-client.md) | Consuming external APIs |81| **URLs** | [urls.md](references/urls.md) | URL generation, signed URLs |82| **Strings** | [strings.md](references/strings.md) | String helpers, UUIDs, slugs |83| **Redirects** | [redirects.md](references/redirects.md) | Redirect responses |8485---8687### Templates (Code Examples)8889#### Controllers & Routes9091| Template | Purpose |92|----------|---------|93| [ApiController.php.md](references/templates/ApiController.php.md) | Complete CRUD controller with service |94| [api-routes.md](references/templates/api-routes.md) | Versioned routes with middleware |95| [routing-examples.md](references/templates/routing-examples.md) | Detailed routing patterns |9697#### Validation & Resources9899| Template | Purpose |100|----------|---------|101| [FormRequest.php.md](references/templates/FormRequest.php.md) | Store/Update Form Requests |102| [validation-rules.md](references/templates/validation-rules.md) | All validation rules reference |103| [ApiResource.php.md](references/templates/ApiResource.php.md) | Resource with relationships |104105#### External APIs106107| Template | Purpose |108|----------|---------|109| [HttpClientService.php.md](references/templates/HttpClientService.php.md) | Reusable HTTP client service |110111---112113## Quick Reference114115### Resource Response116117```php118return PostResource::collection($posts);119return PostResource::make($post);120```121122### Status Codes123124```php125return PostResource::make($post)->response()->setStatusCode(201);126return response()->json(null, 204);127```128129### Form Request130131```php132public function store(StorePostRequest $request): JsonResponse133{134 $post = $this->service->create($request->validated());135 return PostResource::make($post)->response()->setStatusCode(201);136}137```138139### Rate Limiting140141```php142Route::middleware('throttle:60,1')->group(fn () => ...);143```144145### Versioned Routes146147```php148Route::prefix('v1')->group(function () {149 Route::apiResource('posts', PostController::class);150});151```152153### Pagination154155```php156return PostResource::collection(Post::paginate(15));157```158159---160161## Feature Matrix162163| Feature | Status | Reference |164|---------|--------|-----------|165| RESTful Controllers | ✅ | controllers.md |166| API Resources | ✅ | responses.md |167| Form Request Validation | ✅ | validation.md |168| Route Versioning | ✅ | routing.md |169| Route Model Binding | ✅ | routing.md |170| Middleware | ✅ | middleware.md |171| Rate Limiting | ✅ | rate-limiting.md |172| Pagination | ✅ | pagination.md |173| Cursor Pagination | ✅ | pagination.md |174| HTTP Client | ✅ | http-client.md |175| Signed URLs | ✅ | urls.md |176| JSON Responses | ✅ | responses.md |177178---179180## Laravel 13 Notes181182### Attributes pour API Resources183Laravel 13 introduit `#[Collects]` et `#[PreserveKeys]` pour configurer les ResourceCollections via attributs PHP.184185```php186use Illuminate\Http\Resources\Json\ResourceCollection;187use Illuminate\Http\Resources\Attributes\Collects;188use Illuminate\Http\Resources\Attributes\PreserveKeys;189190#[Collects(PostResource::class)]191#[PreserveKeys]192final class PostCollection extends ResourceCollection {}193```194195### JSON:API compliance196Pour les APIs JSON:API (sparse fieldsets, inclusion, links), voir [[laravel-jsonapi]] qui couvre `?include=`, `?fields[type]=`, et la pagination conforme spec.197198## Best Practices199200### DO201- Utiliser API Resources (`JsonResource`) pour toute réponse JSON publique202- Versionner via URL (`/api/v1`) plutôt que via header (lisible, cacheable)203- Rate-limiter par utilisateur ET par IP (`throttle:60,1` + custom limiter)204- Documenter via OpenAPI/Scribe avant de coder l'endpoint205- Préférer `cursor()` pagination pour grandes listes (stable, performant)206207### DON'T208- Retourner directement un Model Eloquent (fuite de colonnes sensibles)209- Mélanger statuts HTTP (toujours 422 pour validation, 401 vs 403)210- Skip Form Request validation (jamais valider en controller)211- Exposer les IDs auto-increment publiquement (préférer UUID/ULID)212- Oublier `PreventRequestForgery` exemption pour les webhooks externes