Back to Tutorials
APIsIntermediate
Building REST APIs with Laravel
A comprehensive guide to building secure and scalable RESTful APIs using the Laravel framework.
James Wilson
January 4, 2026
60 min read
Building REST APIs with Laravel
Learn how to build production-ready RESTful APIs using Laravel's powerful features and best practices.
Setting Up Your API Project
Install Laravel
bash
1composer create-project laravel/laravel api-project
2cd api-project
3php artisan serveConfigure Database
Edit your .env file:
env
1DB_CONNECTION=mysql
2DB_HOST=127.0.0.1
3DB_PORT=3306
4DB_DATABASE=api_db
5DB_USERNAME=root
6DB_PASSWORD=Creating API Resources
Generate Model and Migration
bash
1php artisan make:model Post -m
2php artisan make:controller Api/PostController --api
3php artisan make:resource PostResourceDefine Migration
php
1public function up(): void
2{
3 Schema::create('posts', function (Blueprint $table) {
4 $table->id();
5 $table->string('title');
6 $table->text('content');
7 $table->foreignId('user_id')->constrained()->onDelete('cascade');
8 $table->boolean('published')->default(false);
9 $table->timestamps();
10 });
11}API Controller
php
1namespace App\Http\Controllers\Api;
2
3use App\Http\Controllers\Controller;
4use App\Http\Resources\PostResource;
5use App\Models\Post;
6use Illuminate\Http\Request;
7
8class PostController extends Controller
9{
10 public function index()
11 {
12 $posts = Post::with('user')->paginate(15);
13 return PostResource::collection($posts);
14 }
15
16 public function store(Request $request)
17 {
18 $validated = $request->validate([
19 'title' => 'required|max:255',
20 'content' => 'required',
21 'published' => 'boolean'
22 ]);
23
24 $post = $request->user()->posts()->create($validated);
25
26 return new PostResource($post);
27 }
28
29 public function show(Post $post)
30 {
31 return new PostResource($post->load('user'));
32 }
33
34 public function update(Request $request, Post $post)
35 {
36 $this->authorize('update', $post);
37
38 $validated = $request->validate([
39 'title' => 'sometimes|required|max:255',
40 'content' => 'sometimes|required',
41 'published' => 'boolean'
42 ]);
43
44 $post->update($validated);
45
46 return new PostResource($post);
47 }
48
49 public function destroy(Post $post)
50 {
51 $this->authorize('delete', $post);
52 $post->delete();
53
54 return response()->json(['message' => 'Post deleted'], 200);
55 }
56}API Resources
Transform your models into JSON:
php
1namespace App\Http\Resources;
2
3use Illuminate\Http\Resources\Json\JsonResource;
4
5class PostResource extends JsonResource
6{
7 public function toArray($request): array
8 {
9 return [
10 'id' => $this->id,
11 'title' => $this->title,
12 'content' => $this->content,
13 'published' => $this->published,
14 'author' => new UserResource($this->whenLoaded('user')),
15 'created_at' => $this->created_at->toISOString(),
16 'updated_at' => $this->updated_at->toISOString(),
17 ];
18 }
19}Authentication with Sanctum
Install Sanctum
bash
1php artisan install:apiLogin Controller
php
1public function login(Request $request)
2{
3 $request->validate([
4 'email' => 'required|email',
5 'password' => 'required'
6 ]);
7
8 if (!Auth::attempt($request->only('email', 'password'))) {
9 return response()->json(['message' => 'Invalid credentials'], 401);
10 }
11
12 $user = User::where('email', $request->email)->first();
13 $token = $user->createToken('api-token')->plainTextToken;
14
15 return response()->json([
16 'user' => new UserResource($user),
17 'token' => $token
18 ]);
19}API Routes
php
1// routes/api.php
2Route::post('/login', [AuthController::class, 'login']);
3Route::post('/register', [AuthController::class, 'register']);
4
5Route::middleware('auth:sanctum')->group(function () {
6 Route::apiResource('posts', PostController::class);
7 Route::get('/me', [UserController::class, 'me']);
8});Rate Limiting
php
1// app/Providers/RouteServiceProvider.php
2RateLimiter::for('api', function (Request $request) {
3 return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
4});Testing Your API
php
1public function test_can_create_post(): void
2{
3 $user = User::factory()->create();
4
5 $response = $this->actingAs($user)->postJson('/api/posts', [
6 'title' => 'Test Post',
7 'content' => 'This is a test post',
8 'published' => true
9 ]);
10
11 $response->assertStatus(201)
12 ->assertJsonStructure([
13 'data' => ['id', 'title', 'content', 'published']
14 ]);
15}Conclusion
You now have a solid foundation for building RESTful APIs with Laravel. Remember to implement proper validation, authentication, and error handling in production!