Chapter 5: Backend API Development & Authentication
Introduction
Modern dashboards often require backend APIs to facilitate communication with frontend applications, mobile clients, or external integrations. This chapter covers creating RESTful APIs in Laravel, implementing authentication using Sanctum or Passport, securing API access, and best practices for API versioning and documentation.
Creating RESTful APIs with Laravel
1. Understanding RESTful API Principles
Before implementing our API, it’s essential to follow RESTful conventions:
- Endpoints should represent resources (e.g.,
/api/users,/api/orders). - Use standard HTTP verbs:
GET– Retrieve data.POST– Create new resources.PUT/PATCH– Update existing resources.DELETE– Remove resources.
- Follow stateless communication – Each request must include authentication and required data.
2. Defining API Routes
Laravel stores API routes in routes/api.php. These routes are grouped under the api middleware by default, ensuring stateless handling.
Example API routes for user management:
Route::prefix('v1')->group(function () {
Route::get('/users', [UserController::class, 'index']);
Route::post('/users', [UserController::class, 'store']);
Route::get('/users/{id}', [UserController::class, 'show']);
Route::put('/users/{id}', [UserController::class, 'update']);
Route::delete('/users/{id}', [UserController::class, 'destroy']);
});
3. Building API Controllers
Generate an API controller:
php artisan make:controller UserController --api
This creates a resourceful controller without view-related methods. Inside UserController.php, define methods:
public function index() {
return User::paginate(10);
}
This returns paginated user data in JSON format.
4. Using API Resource Classes
Laravel provides Resource classes (App\Http\Resources) to structure API responses consistently:
class UserResource extends JsonResource {
public function toArray($request) {
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'role' => $this->role->name,
];
}
}
Usage in the controller:
return UserResource::collection(User::paginate(10));
5. Testing APIs (Manual & Automated)
- Use Postman or Insomnia to manually test endpoints.
- Automate tests using PHPUnit:
public function test_users_list() {
$response = $this->getJson('/api/v1/users');
$response->assertStatus(200);
}
Run tests with:
php artisan test
Securing APIs with Sanctum or Passport
1. When to Use Sanctum vs. Passport
| Feature | Sanctum | Passport |
|---|---|---|
| API Type | SPA, Mobile | OAuth2, Third-party apps |
| Token Type | Personal Access Tokens | Access + Refresh Tokens |
| Simplicity | Easier | More complex but powerful |
- Use Sanctum for SPAs and first-party mobile apps.
- Use Passport for OAuth2 authentication and third-party API access.
2. Implementing Sanctum
Install Sanctum:
composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate
Update app/Http/Kernel.php:
'api' => [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
Protect API routes:
Route::middleware('auth:sanctum')->get('/orders', [OrderController::class, 'index']);
Issuing an authentication token:
public function login(Request $request) {
$user = User::where('email', $request->email)->first();
if (! $user || ! Hash::check($request->password, $user->password)) {
return response()->json(['message' => 'Unauthorized'], 401);
}
return response()->json(['token' => $user->createToken('api-token')->plainTextToken]);
}
Front-end apps must send this token via the Authorization header:
Authorization: Bearer {token}
3. Implementing Passport (Overview)
To install Passport:
composer require laravel/passport
php artisan passport:install
Use Passport authentication:
Route::middleware('auth:api')->get('/profile', function (Request $request) {
return $request->user();
});
Authorization & Permissions
1. Using Policies for Role-Based Access
Generate a policy:
php artisan make:policy UserPolicy --model=User
Define authorization logic in UserPolicy.php:
public function delete(User $user, User $targetUser) {
return $user->isAdmin();
}
Use in controller:
$this->authorize('delete', $user);
2. Rate Limiting
Apply rate limiting middleware:
Route::middleware('throttle:60,1')->get('/reports', [ReportController::class, 'index']);
3. Securing API Keys & External Access
If exposing an API to third parties, require API keys in headers:
if ($request->header('X-API-KEY') !== config('services.api_key')) {
return response()->json(['error' => 'Unauthorized'], 401);
}
API Versioning and Documentation
1. Implementing API Versioning
Maintain backward compatibility by prefixing API routes:
Route::prefix('v1')->group(function () {
Route::get('/users', [UserController::class, 'index']);
});
Future changes go under /api/v2/... while keeping /api/v1/... functional.
2. Documenting APIs with Swagger/OpenAPI
Use Laravel Scribe or Swagger to generate API documentation:
composer require knuckleswtf/scribe
php artisan scribe:generate
This auto-generates interactive API docs.
Summary
By the end of this chapter, we have: ✅ Built RESTful APIs in Laravel. ✅ Implemented authentication with Sanctum. ✅ Secured API endpoints with middleware and policies. ✅ Applied rate limiting and API versioning. ✅ Learned how to document APIs for better usability.
Quiz – API Development
- What is the main difference between Laravel Sanctum and Laravel Passport?
- How can you protect an API route so that only authenticated users with a valid token can access it?
- Why is API versioning important, and how can you implement it in Laravel?
By completing this chapter, your Laravel dashboard is now API-ready, supporting authentication, security, and scalable API development.