Building Scalable REST APIs with
Laravel 11 - A Complete Guide

Everything you need to know to design, build and secure a production-ready REST API using Laravel 11. Covers route structure, API resources, authentication with Sanctum, rate limiting, versioning and more.

Laravel 11 - REST API - Complete Guide

Introduction

REST APIs are the backbone of modern web applications. Whether you are powering a mobile app, a single-page application or a third-party integration, a well-designed API makes all the difference. In this guide, we will build a production-grade REST API from scratch using Laravel 11.

Prerequisites: PHP 8.2+, Composer, basic Laravel knowledge and a clear understanding of REST basics.

1. Project Setup

Start with a fresh Laravel project and install the API scaffolding. Laravel 11 keeps the application skeleton smaller, which makes API-focused projects easier to reason about.

  
bash
composer create-project laravel/laravel laravel-api cd laravel-api php artisan install:api

The install:api command prepares Sanctum, API routes and migrations so you can focus on application design instead of setup chores.

2. API Route Structure

Version your API from day one. A small prefix like v1 gives you room to ship future breaking changes without disrupting existing clients.

  
php
use App\Http\Controllers\Api\V1\AuthController; use App\Http\Controllers\Api\V1\PostController; Route::prefix('v1')->group(function () { Route::post('/register', [AuthController::class, 'register']); Route::post('/login', [AuthController::class, 'login']); Route::middleware('auth:sanctum')->group(function () { Route::apiResource('posts', PostController::class); Route::post('/logout', [AuthController::class, 'logout']); }); });

3. API Resources

Never return raw Eloquent models from an API. Resources let you shape responses, hide private fields and include relationships only when they were intentionally loaded.

  
php
class PostResource extends JsonResource { public function toArray(Request $request): array { return [ 'id' => $this->id, 'title' => $this->title, 'slug' => $this->slug, 'excerpt' => $this->excerpt, 'body' => $this->when($request->routeIs('posts.show'), $this->body), 'author' => new UserResource($this->whenLoaded('user')), 'created_at' => $this->created_at->toDateTimeString(), ]; } }

Pro tip: Use when() and whenLoaded() to avoid over-fetching and N+1 query issues.

4. Authentication with Sanctum

Sanctum is a strong fit for token-based APIs. Keep login responses clear, expire tokens when possible and delete the current access token on logout.

  
php
public function login(LoginRequest $request): JsonResponse { if (! Auth::attempt($request->only('email', 'password'))) { return response()->json(['message' => 'Invalid credentials'], 401); } $token = $request->user()->createToken('api-token', ['*'], now()->addDays(30)); return response()->json([ 'user' => new UserResource($request->user()), 'token' => $token->plainTextToken, ]); }

5. Form Requests and Error Handling

Keep controllers thin by moving validation into Form Request classes. This creates a reusable validation layer and makes error responses predictable.

  
php
class StorePostRequest extends FormRequest { public function rules(): array { return [ 'title' => ['required', 'string', 'max:255'], 'body' => ['required', 'string'], 'status' => ['required', Rule::in(['draft', 'published'])], ]; } }

6. Rate Limiting

Rate limits protect login endpoints and high-cost API routes. Laravel lets you define limits by IP, authenticated user or another request-specific key.

Important: Return clear 429 responses so clients know when to retry.

7. Testing Your API

Production APIs need tests around authentication, validation, permissions and response structure. Laravel HTTP tests make those checks readable.

  
php
it('can create a post when authenticated', function () { $user = User::factory()->create(); $this->actingAs($user, 'sanctum') ->postJson('/api/v1/posts', [ 'title' => 'My First Post', 'body' => 'Hello world', 'status' => 'published', ]) ->assertCreated() ->assertJsonPath('data.title', 'My First Post'); });

Conclusion

A scalable Laravel API is built from small repeatable decisions: version routes, transform responses with Resources, authenticate with Sanctum, validate with Form Requests, apply rate limits and protect everything with tests.

AM
Aditya Mandal
Full Stack Developer

I'm a freelance Full Stack Developer with experience building scalable web apps with Laravel, WordPress and REST APIs. I write practical tutorials from real project experience.

Previous Post
How to Build a Custom WordPress Theme from Scratch