About laravel-api
A Laravel development skill for building RESTful APIs. It guides developers through resource-based JSON responses, validation, authentication, versioning, pagination, rate limiting, and outbound HTTP requests.
Key features
- 01API Resources for JSON responses
- 02Sanctum authentication
- 03Form Request validation
- 04Versioned routes and rate limits
- 05Offset and cursor pagination
- 06HTTP client for external APIs
Use cases
- 01Build versioned REST endpoints
- 02Validate and authorize API input
- 03Paginate large API result sets
- 04Consume external services over HTTP
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ fusengine/ claude-plugins --skill laravel-apiAfter installing, type/laravel-apiin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
references/controllers.mdhttp-client.mdmiddleware.mdpagination.mdrate-limiting.mdredirects.mdrequests.mdresponses.mdrouting.mdstrings.mdurls.mdvalidation.mdreferences/templates/api-routes.mdApiController.php.mdApiResource.php.mdFormRequest.php.mdHttpClientService.php.mdrouting-examples.mdvalidation-rules.mdDetails
From the project READMELaravel 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 for API Resources
Laravel 13 introduces #[Collects] and #[PreserveKeys] to configure ResourceCollections via PHP attributes.
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
For JSON:API APIs (sparse fieldsets, includes, links), see [[laravel-jsonapi]], which covers ?include=, ?fields[type]=, and spec-compliant pagination.
Best Practices
DO
- Use API Resources (
JsonResource) for every public JSON response - Version via URL (
/api/v1) rather than via header (readable, cacheable) - Rate-limit per user AND per IP (
throttle:60,1+ custom limiter) - Document via OpenAPI/Scribe before coding the endpoint
- Prefer
cursor()pagination for large lists (stable, performant)
DON'T
- Return an Eloquent Model directly (leaks sensitive columns)
- Mix up HTTP statuses (always 422 for validation, 401 vs 403)
- Skip Form Request validation (never validate in the controller)
- Expose auto-increment IDs publicly (prefer UUID/ULID)
- Forget the
PreventRequestForgeryexemption for external webhooks