Laravel ‐ Chapter 13 - pierre-akhrass/Lavarel-Docs GitHub Wiki
Chapter 13: REST APIs in Laravel
This chapter guides you through building a RESTful API using Laravel 11+, including authentication, routing, controller setup, request validation, response formatting, exception handling, and API testing.
1. What is a REST API?
A REST (Representational State Transfer) API is an interface between systems that uses HTTP methods (GET, POST, PUT, DELETE) to access and modify resources, often returned in JSON format.
api.php
in Laravel 11
2. Setting Up Laravel 11 no longer publishes the api.php
route file by default.
To enable it:
php artisan install:api
This:
- Publishes
routes/api.php
- Installs Laravel Sanctum for authentication
The API endpoints will now be available at URLs like:
http://yourdomain.test/api/post
3. Defining API Routes
In routes/api.php
:
use App\Http\Controllers\Api\CategoryController;
use App\Http\Controllers\Api\PostController;
Route::resource('category', CategoryController::class)->except(['create', 'edit']);
Route::resource('post', PostController::class)->except(['create', 'edit']);
except(['create', 'edit'])
Since you're building an API, you don’t need the routes that return HTML forms (create and edit), because APIs usually send/receive JSON, not HTML forms.
4. Creating API Controllers
Generate controllers:
php artisan make:controller Api/PostController -m Post
php artisan make:controller Api/CategoryController -m Category
Each controller uses:
- Form Requests (
StoreRequest
,PutRequest
) for validation - JSON responses using
response()->json()
CategoryController
Example: The below code fetches ten categories per page.
public function index(): JsonResponse {
return response()->json(Category::paginate(10));
}
5. Custom JSON Output
To include relationships: the below code tells Laravel to load the related Category model for each post.
public function index() {
return response()->json(Post::with('category')->paginate(10));
}
6. Exception Handling
In bootstrap/app.php
:
->withExceptions(function (Exceptions $exceptions) {
$exceptions->render(function (NotFoundHttpException $e, $request) {
if ($request->expectsJson()) {
return response()->json('Not found', 404);
}
});
})
7. Testing the API (Postman)
Use Postman to test API routes.
Method | Endpoint |
---|---|
GET | /api/post |
GET | /api/post/{id} |
POST | /api/post |
PUT | /api/post/{id} |
DELETE | /api/post/{id} |
Use Accept: application/json
header.
8. Custom Methods
All Records:
public function all(): JsonResponse {
return response()->json(Post::get());
}
By Slug:
public function slug($slug): JsonResponse {
return response()->json(Post::with('category')->where('slug', $slug)->firstOrFail());
}
Route:
Route::get('post/slug/{slug}', [PostController::class, 'slug']);
Or with route binding:
Route::get('post/slug/{post:slug}', [PostController::class, 'slug']);
9. Authentication with Sanctum
Sanctum provides token-based authentication.
Setup:
Already installed with:
php artisan install:api
Enable in User.php
:
hasApiTokens is added to the User model to enable token creation and validation.
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable {
use HasApiTokens, ...;
}
Login Controller:
public function login(Request $request) {
$request->validate([
'email' => 'required|email',
'password' => 'required',
]);
if (auth()->attempt($request->only('email', 'password'))) {
$token = auth()->user()->createToken('api-token')->plainTextToken;
return response()->json($token);
}
return response()->json('Invalid credentials', 422);
}
Add route:
Route::post('user/login', [UserController::class, 'login']);
Use header: When the client (e.g., frontend app, mobile app) calls API routes that require authentication, it must: Include the token in the HTTP Authorization header like this: (used to access protected resources)
Authorization: Bearer YOUR_TOKEN_HERE
10. Protecting Routes
Use Sanctum middleware: This middleware:
Checks if the incoming API request includes a valid Sanctum token in the Authorization: Bearer TOKEN header. If valid, the request proceeds and the user is authenticated. If not valid or missing, Laravel returns a 401 Unauthorized response.
Route::middleware('auth:sanctum')->group(function () {
Route::resource('category', CategoryController::class)->except(['create', 'edit']);
Route::resource('post', PostController::class)->except(['create', 'edit']);
});
11. Using Axios or Vue for Authentication
When using Laravel Sanctum to protect your API routes, especially when your frontend and backend are served from the same domain (or trusted subdomains), Laravel expects CSRF protection on state-changing requests (like POST, PUT, DELETE).
Even though Sanctum uses token-based auth, CSRF tokens are still required to protect against cross-site request forgery in some setups (like SPA on the same domain).
In resources/js/bootstrap.js
:
axios.defaults.withCredentials = true;
axios.defaults.withXSRFToken = true;
Example:
axios.get('/sanctum/csrf-cookie').then(() => {
axios.post('/api/user/login', {
email: '[email protected]',
password: '12345'
}).then(res => console.log(res.data));
});