Laravel · Bab 12
Lab 8: Dasar REST API & JSON
Membuka pintu JSON untuk aplikasi Laravel — memahami REST, mengaktifkan routes/api.php, membuat controller API ber-versi, dan menguji endpoint dengan Klien API.
Sampai Lab 7, aplikasi kita melayani manusia lewat browser dengan halaman HTML. Di dunia nyata, data yang sama juga dipakai aplikasi lain: aplikasi ponsel, frontend Vue atau React, atau sistem mitra. Mereka tidak butuh HTML; mereka butuh data mentah dalam format JSON. Bagian ini mengajarkan cara menyajikannya dengan Laravel. Contoh kode memakai studi kasus perpustakaan (books, authors); terapkan polanya ke produk.
Alur Langkah
- Daftarkan routing API di
bootstrap/app.phpdan buat berkasroutes/api.php. - Buat controller
Api/V1/ProductControllerdenganindex()danshow()yang mengembalikan JSON. - Daftarkan rute
apiResourceber-versi diroutes/api.php, lalu uji lewat tab Klien API.
REST dan JSON dalam Satu Menit
REST adalah kesepakatan cara memberi nama alamat dan memakai method HTTP agar API mudah ditebak:
| Method | Alamat | Arti |
|---|---|---|
| GET | /api/v1/books | ambil daftar buku |
| GET | /api/v1/books/7 | ambil buku ber-ID 7 |
| POST | /api/v1/books | buat buku baru |
| PUT | /api/v1/books/7 | ubah buku 7 |
| DELETE | /api/v1/books/7 | hapus buku 7 |
Kata benda jamak di alamat (books), kata kerjanya ada di method. Responsnya berupa JSON:
{ "data": { "id": 7, "title": "Laskar Pelangi", "author": { "name": "Andrea Hirata" } } }
Membungkus hasil dalam kunci data adalah kebiasaan industri: nanti kita bisa menambah kunci lain (misalnya meta untuk pagination) tanpa merusak klien yang sudah ada.
Mengaktifkan routes/api.php
Laravel 11 sengaja tidak menyertakan routing API supaya proyek yang tidak membutuhkannya tetap ringan. Perintah install:api menambahkannya, tetapi ia juga memasang paket tambahan lewat Composer. Di lab ini kita menulisnya manual, dan hasilnya sama: satu baris di bootstrap/app.php dan satu berkas rute.
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
Semua rute di routes/api.php otomatis mendapat awalan /api dan tidak memakai middleware sesi/CSRF seperti routes/web.php. Itu sebabnya POST ke API tidak butuh @csrf.
Controller API dan Route Model Binding
namespace App\Http\Controllers\Api\V1;
use App\Http\Controllers\Controller;
use App\Models\Book;
class BookController extends Controller
{
public function index()
{
return response()->json(['data' => Book::with('author')->get()]);
}
public function show(Book $book)
{
return response()->json(['data' => $book->load('author')]);
}
}
response()->json() mengubah array atau model Eloquent menjadi JSON dengan header Content-Type: application/json. Pada show(Book $book), Route Model Binding (Lab 6) bekerja sama seperti di web: /api/v1/books/7 mengisi $book dengan buku ber-ID 7, atau otomatis menjawab 404 bila tidak ada. Bila header Accept: application/json dikirim, 404 itu berbentuk JSON; tanpa header itu Laravel menampilkan halaman 404 HTML.
apiResource dan Versi API
Route::resource membuat tujuh rute, termasuk form create dan edit yang tidak dibutuhkan API. Route::apiResource hanya membuat lima, dan ->only([...]) membatasinya lagi:
Route::prefix('v1')->name('api.v1.')->group(function () {
Route::apiResource('books', BookController::class)->only(['index', 'show']);
});
prefix('v1') memberi alamat /api/v1/books. Versi di alamat membuat kamu bisa merilis /api/v2 kelak tanpa merusak aplikasi yang masih memakai v1. name('api.v1.') mencegah nama rute bertabrakan dengan rute web yang namanya mirip.
Mencoba dengan Klien API
Buka tab Klien API di panel bawah lab. Pilih method, isi path (harus diawali /api/), lalu Kirim. Header Accept: application/json terisi otomatis, dan itu penting:
Hasil yang Diharapkan
GET /api/v1/products menjawab 200 dengan daftar produk beserta kategorinya di kunci data. GET /api/v1/products/1 menjawab satu produk. GET /api/v1/products/9999 menjawab 404 berformat JSON bila header Accept: application/json dikirim.