Sampai sekarang project blog kamu hanya melayani request melalui web browser dengan response HTML via Blade. Tapi bagaimana kalau kamu ingin aplikasi mobile atau frontend SPA bisa mengakses data blog-mu dalam format JSON? Saatnya kita upgrade dan expose data sebagai REST API!
REST API memungkinkan klien lain (mobile app, Single Page Application, atau sistem pihak ketiga) mengakses dan memanipulasi data kamu melalui endpoint HTTP yang konsisten dan terstandar. Dan yang seru: Laravel punya fitur-fitur built-in yang membuat pembuatan API menjadi super mudah dan clean.
Perbedaan Web Routes dan API Routes
Sebelum mulai coding, penting kamu pahami perbedaan antara web routes dan API routes di Laravel. Di file routes/web.php, kamu define routes yang return HTML response—biasanya via Blade template. Sementara di file routes/api.php, kamu define routes yang return JSON response.
Laravel sudah menyiapkan routes/api.php secara default. Semua routes yang kamu define di sini akan otomatis di-prefix dengan /api. Jadi kalau kamu membuat route /posts di api.php, endpoint lengkapnya adalah /api/posts.
Ini cara yang baik untuk memisahkan concern — web dan API berjalan di jalur berbeda, middleware berbeda, dan format response berbeda. Bagus untuk scalability dan maintainability.
Membuat API Controller untuk Posts
Untuk mengikuti best practice, kita akan membuat Controller khusus untuk API yang terpisah dari Controller web. Jalankan command berikut di terminal:
php artisan make:controller Api\PostController --api
Flag --api membuat Controller dengan method-method CRUD yang relevan untuk API (index, show, store, update, destroy). Ayo lihat struktur Controller yang dihasilkan:
<?php
namespace App\Http\Controllers\Api;
use App\Models\Post;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Resources\PostResource;
class PostController extends Controller
{
public function index()
{
$posts = Post::all();
return PostResource::collection($posts);
}
public function show($id)
{
$post = Post::findOrFail($id);
return new PostResource($post);
}
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|string|max:255',
'content' => 'required|string',
]);
$post = Post::create($validated);
return new PostResource($post);
}
public function update(Request $request, $id)
{
$post = Post::findOrFail($id);
$validated = $request->validate([
'title' => 'required|string|max:255',
'content' => 'required|string',
]);
$post->update($validated);
return new PostResource($post);
}
public function destroy($id)
{
$post = Post::findOrFail($id);
$post->delete();
return response()->json(['message' => 'Post deleted successfully']);
}
}
Notice bagaimana kita menggunakan PostResource untuk format response? Kita akan bahas itu sebentar lagi. Tapi sebelumnya, kita perlu define routes di routes/api.php:
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Api\PostController;
Route::apiResource('posts', PostController::class);
Method apiResource() secara otomatis generate semua route RESTful yang kita butuhkan: GET /api/posts (list), GET /api/posts/{id} (detail), POST /api/posts (create), PUT/PATCH /api/posts/{id} (update), DELETE /api/posts/{id} (delete). Sangat berguna!
Menggunakan API Resource untuk Format JSON Rapi
API Resource adalah kelas khusus di Laravel yang digunakan untuk transformasi model ke format JSON yang konsisten dan clean. Buat PostResource dengan command:
php artisan make:resource PostResource
Sekarang edit file app/Http/Resources/PostResource.php:
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class PostResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'content' => $this->content,
'author' => $this->author_id,
'created_at' => $this->created_at->format('Y-m-d H:i:s'),
'updated_at' => $this->updated_at->format('Y-m-d H:i:s'),
];
}
}
PostResource bertanggung jawab menentukan field mana yang di-expose, format tanggal, dan struktur data yang dikirim ke klien. Dengan pendekatan ini, kamu punya satu tempat untuk mengatur format JSON—jadi kalau ada perubahan, kamu tinggal ubah di satu tempat saja.
Contoh response JSON dari endpoint GET /api/posts:
{
"data": [
{
"id": 1,
"title": "Belajar Laravel 13",
"content": "Lorem ipsum dolor sit amet...",
"author": 1,
"created_at": "2025-01-15 10:30:00",
"updated_at": "2025-01-15 10:30:00"
},
{
"id": 2,
"title": "REST API dengan Laravel",
"content": "Tutorial membuat REST API...",
"author": 1,
"created_at": "2025-01-16 14:20:00",
"updated_at": "2025-01-16 14:20:00"
}
]
}
Perhatikan struktur JSON di atas—Laravel otomatis membungkus array resource dengan key data. Ini adalah konvensi JSON:API yang baik untuk konsistensi.
Test API dengan Hoppscotch
Sekarang kita coba test endpoint yang baru dibuat. Kamu bisa menggunakan Hoppscotch, sebuah REST client yang user-friendly berbasis browser. Tidak perlu install, buka saja di browser.
Langkah-langkah test:
- Buka Hoppscotch.io di browser
- Di bagian URL, masukkan
http://localhost:8000/api/posts(sesuaikan port jika kamu pakai yang berbeda) - Pastikan method adalah GET
- Klik tombol "Send"
- Lihat response JSON di panel sebelah kanan
Untuk test POST (create), ubah method ke POST, masukkan body JSON:
{
"title": "Post Baru dari API",
"content": "Ini adalah post yang dibuat via API REST"
}
Pastikan header Content-Type: application/json sudah set (biasanya Hoppscotch set otomatis). Klik Send, dan kamu akan melihat post baru tercipta dengan response JSON yang rapi.
Untuk test DELETE, ubah method ke DELETE dan masukkan URL http://localhost:8000/api/posts/1 (ganti 1 dengan ID post yang ingin dihapus). Klik Send, dan post akan terhapus.
Error Handling dan HTTP Status Code
API yang baik harus handle error dengan proper dan mengembalikan HTTP status code yang sesuai. Mari kita improve PostController kita dengan error handling yang lebih robust:
<?php
namespace App\Http\Controllers\Api;
use App\Models\Post;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Resources\PostResource;
class PostController extends Controller
{
public function index()
{
try {
$posts = Post::paginate(10);
return PostResource::collection($posts);
} catch (\Exception $e) {
return response()->json([
'message' => 'Failed to fetch posts',
'error' => $e->getMessage()
], 500);
}
}
public function show($id)
{
$post = Post::find($id);
if (!$post) {
return response()->json([
'message' => 'Post not found'
], 404);
}
return new PostResource($post);
}
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|string|max:255',
'content' => 'required|string',
]);
$post = Post::create($validated);
return response()->json(
new PostResource($post),
201
);
}
}
Beberapa tips penting:
- 200 OK: Request berhasil, gunakan untuk GET dan update/delete yang sukses
- 201 Created: Resource baru berhasil dibuat via POST
- 400 Bad Request: Validation error, data tidak sesuai format yang diharapkan
- 404 Not Found: Resource tidak ditemukan
- 500 Internal Server Error: Terjadi kesalahan di server
Laravel akan otomatis mengembalikan 422 Unprocessable Entity jika validation gagal—kamu tidak perlu handle manual. Ini behavior default dari Form Request validation di Laravel.
Langkah Berikutnya: Autentikasi API
Saat ini API kamu bisa diakses siapa saja—tidak ada autentikasi. Untuk production, kamu harus secure endpoint ini dengan autentikasi. Laravel menyediakan Laravel Sanctum yang powerful untuk token-based authentication.
Namun Sanctum itu topik besar dan akan kita bahas di artikel selanjutnya. Untuk sekarang, kamu sudah punya REST API yang fully functional dan bisa dikonsumsi oleh mobile app atau frontend SPA apapun!
Kalau kamu mau deep dive lebih lanjut, baca dokumentasi resmi API Resource di Laravel. Di sana ada banyak contoh advanced seperti nested resource dan conditional attributes.
Kesimpulan
Di artikel ini kita udah belajar cara membuat REST API sederhana dengan Laravel 13—dari setup API routes, membuat API Controller, menggunakan API Resource untuk format JSON yang konsisten, sampai cara test endpoint dengan Hoppscotch.
REST API membuka banyak kemungkinan: aplikasi mobile bisa consume data kamu, frontend SPA bisa berkomunikasi tanpa refresh halaman, dan sistem pihak ketiga bisa terintegrasi dengan mudah. Dengan Laravel, semua itu jadi sangat straightforward.
Kalau kamu belum familiar dengan Controller, review dulu article #5 tentang Controller Laravel 13. Dan jangan lupa untuk revisit project blog kamu—sekarang project ini serve data dalam dua format: HTML (via web routes) dan JSON (via API routes).
Episode berikutnya kita akan add autentikasi ke API dengan Sanctum. Stay tuned! 🚀