Laravel 11 API Best Practices: From Junior to Senior in 10 Minutes
Building APIs with Laravel? Here are the patterns that separate juniors from seniors.
1. Always Use Form Requests
Stop putting validation in controllers. It is messy and hard to test.
class StoreOrderRequest extends FormRequest
{
public function rules(): array
{
return [
'product_id' => 'required|exists:products,id',
'quantity' => 'required|integer|min:1|max:100',
];
}
}
2. Use API Resources for Response Formatting
Never return Eloquent models directly.
class OrderResource extends JsonResource
{
public function toArray($request): array
{
return [
'id' => $this->id,
'total' => number_format($this->total, 2),
'status' => $this->status,
'items' => OrderItemResource::collection($this->items),
];
}
}
3. Implement Proper Rate Limiting
Route::middleware('throttle:60,1')->group(function () {
Route::apiResource('orders', OrderController::class);
});
4. Cache Aggressively
$products = Cache::tags(['products'])->remember(
'products-page-' . $page,
3600,
fn() => Product::paginate(20)
);
5. Use Jobs for Heavy Operations
ProcessOrder::dispatch($order)
->onQueue('orders')
->delay(now()->addMinutes(5));
6. Proper Error Handling
$this->renderable(function (NotFoundHttpException $e, Request $request) {
if ($request->expectsJson()) {
return response()->json([
'error' => 'Resource not found',
], 404);
}
});
7. Use Sanctum for API Tokens
$token = $user->createToken('mobile-app', ['read', 'write']);
8. Database Transactions
DB::transaction(function () use ($orderData, $items) {
$order = Order::create($orderData);
foreach ($items as $item) {
$order->items()->create($item);
}
});
Follow for more Laravel and e-commerce tips.