Routing

Rute GET/POST, parameter rute, dan rute bernama pada berkas routes/web.php.

Daftar isi

Routing adalah mekanisme yang mencocokkan URI dan metode HTTP sebuah permintaan dengan rute yang menanganinya. Topik ini membahas cara mendaftarkan rute pada routes/web.php, mulai dari rute berbasis closure, pencocokan metode HTTP, parameter rute, sampai rute bernama. Setiap pernyataan perilaku diverifikasi dengan mengirim permintaan sintetis ke proyek contoh.

Rute dasar pada routes/web.php#

Rute paling sederhana menerima URI dan sebuah closure, yaitu fungsi tanpa nama yang dijalankan ketika permintaan cocok, dan nilai yang dikembalikan fungsi tersebut menjadi isi respons. Pada proyek baru, routes/web.php berisi satu rute seperti berikut.

php Isi routes/web.php pada proyek baru
// tidak-dijalankan
<?php

use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    return view('welcome');
});

Metode statis Route::get() mendaftarkan rute untuk metode HTTP GET, sedangkan pemanggilan view('welcome') di dalamnya menetapkan templat Blade bernama welcome sebagai isi respons. Semua rute pada berkas ini otomatis diberi grup middleware web, sehingga permintaan yang melewatinya memperoleh session, proteksi CSRF, dan enkripsi cookie. Rute tambahan cukup ditulis berdampingan di berkas yang sama.

Berkas berikut memperluas rute proyek contoh dengan satu rute POST, satu rute closure yang mengembalikan teks, dan satu rute berparameter.

php routes/web.php
// tidak-dijalankan
<?php

use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    return view('welcome');
});

Route::post('/simpan', function () {
    return 'Disimpan.';
});

Route::get('/tentang', function () {
    return 'Halaman tentang aplikasi catatan.';
});

Route::get('/salam/{nama}', function (string $nama) {
    return 'Halo, ' . $nama . '!';
})->whereAlpha('nama')->name('salam');

Berkas di atas ditempatkan sebagai routes/web.php, lalu daftar rute yang terdaftar diperiksa dengan perintah route:list. Opsi --except-vendor menyembunyikan rute milik paket agar tabel hanya memuat rute aplikasi, termasuk rute API proyek contoh.

bash
# salin berkas rute contoh ke proyek uji
cp web.php ~/aplikasi-catatan/routes/web.php
cd ~/aplikasi-catatan
# siapkan routes/api.php minimal agar keluaran route:list tetap sama
cat > routes/api.php <<'PHP'
<?php

use Illuminate\Support\Facades\Route;

Route::get('/status', function () {
    return response()->json(['status' => 'ok']);
});
PHP
# tampilkan rute aplikasi tanpa rute milik paket
php artisan route:list --except-vendor
text Keluaran
  GET|HEAD   / .............................................. routes/web.php:5
  GET|HEAD   api/status ..................................... routes/api.php:5
  GET|HEAD   salam/{nama} .......................... salam › routes/web.php:17
  POST       simpan ......................................... routes/web.php:9
  GET|HEAD   tentang ....................................... routes/web.php:13

                                                            Showing [5] routes

Setiap baris tabel menampilkan metode HTTP, URI, dan lokasi definisi rutenya. Kolom tengah memuat nama rute apabila rute diberi nama, seperti salam pada rute berparameter. Baris berawalan api/ berasal dari berkas routes/api.php yang dibuat pada blok perintah di atas, sehingga opsi --except-vendor tidak menyembunyikannya. Daftar ini menjadi alat periksa cepat setiap kali rute baru ditambahkan.

Mencocokkan metode HTTP#

Router menyediakan satu metode pendaftaran untuk setiap kata kerja HTTP, yaitu Route::get(), Route::post(), Route::put(), Route::patch(), Route::delete(), dan Route::options(). Metode Route::match() menerima daftar kata kerja sekaligus, sedangkan Route::any() menerima semua kata kerja. Rute POST pada berkas di atas membalas permintaan ke /simpan dengan metode POST.

Ketidakcocokan metode tidak menghasilkan 404, melainkan status 405 Method Not Allowed. Perilakunya dapat diverifikasi dengan mengirim permintaan GET ke rute POST yang baru didaftarkan.

bash
cd ~/aplikasi-catatan
# kirim permintaan GET ke rute yang hanya menerima POST
php artisan tinker --execute='echo app(\Illuminate\Contracts\Http\Kernel::class)->handle(\Illuminate\Http\Request::create("/simpan"))->getStatusCode();'
text Keluaran
405

Status 405 muncul karena URI /simpan cocok dengan rute yang terdaftar, tetapi metode GET tidak termasuk kata kerja yang diterimanya. Perlu diperhatikan bahwa rute POST pada berkas web mensyaratkan formulir HTML yang mengirim ke /simpan menyertakan token CSRF melalui direktif @csrf, karena permintaan tanpa token ditolak.

Parameter rute#

Segmen URI yang dituliskan di dalam kurung kurawal menjadi parameter rute, dan nilainya disuntikkan ke closure berdasarkan urutan kemunculannya. Rute /salam/{nama} menerima satu parameter, dan formatnya dapat dibatasi dengan metode whereAlpha() yang hanya menerima huruf. Permintaan dengan parameter yang memenuhi batasan itu dibalas seperti berikut.

bash
cd ~/aplikasi-catatan
# kirim permintaan dengan parameter huruf
php artisan tinker --execute='echo app(\Illuminate\Contracts\Http\Kernel::class)->handle(\Illuminate\Http\Request::create("/salam/Dewi"))->getContent();'
text Keluaran
Halo, Dewi!

Nilai Dewi mengisi parameter {nama} sehingga closure mengembalikan sapaan yang memuatnya. Apabila segmen tersebut berisi karakter lain di luar batasan, rute tidak cocok dan responsnya berupa status 404.

bash
# kirim permintaan dengan parameter angka pada batasan huruf
php artisan tinker --execute='echo app(\Illuminate\Contracts\Http\Kernel::class)->handle(\Illuminate\Http\Request::create("/salam/123"))->getStatusCode();'
text Keluaran
404

Selain parameter wajib, router mendukung parameter opsional yang ditandai tanda tanya, misalnya Route::get('/halo/{nama?}', function (?string $nama = null) {...}), dan nilai baku wajib diberikan pada argumen closure-nya. Batasan format juga dapat ditulis dengan whereNumber() untuk angka atau where() beserta pola reguler khusus.

Rute bernama#

Metode name() memberi nama pada rute, dan nama itu menjadi pengganti URI ketika URL perlu dibangkitkan. Pada berkas rute di atas, rute /salam/{nama} diberi nama salam. Helper route() menghasilkan URL dari nama rute beserta parameternya, sehingga perubahan URI di kemudian hari tidak merusak tautan yang dibangkitkan.

bash
cd ~/aplikasi-catatan
# bangkitkan URL dari nama rute beserta parameternya
php artisan tinker --execute='echo route("salam", ["nama" => "Budi"]);'
text Keluaran
http://localhost:8000/salam/Budi

Helper route() menggantikan bagian {nama} dengan nilai Budi dan menambahkan awalan URL aplikasi yang berasal dari konfigurasi. Nama rute juga digunakan oleh redirect()->route() dan to_route() untuk membuat pengalihan. Nama rute harus unik di seluruh aplikasi karena nama yang sama membuat tujuan pembangkitan URL tidak pasti.

Daftar nama yang sudah terpasang dapat diperiksa melalui php artisan route:list, karena keluarannya menyertakan kolom nama di samping URI dan aksi setiap rute. Pada proyek yang rutenya sudah banyak, penyaringan dengan opsi --name=... mempersempit keluaran ke rute yang namanya cocok, sehingga nama yang benar untuk route() tetap mudah ditemukan tanpa membuka berkas rute satu per satu.

Kesalahan umum#

Kesalahan pertama adalah menganggap setiap URI mendapatkan respons. Permintaan yang URI-nya tidak cocok dengan rute mana pun dibalas status 404, dan verifikasinya cukup dengan mengirim permintaan ke URI sembarang.

bash
cd ~/aplikasi-catatan
# kirim permintaan ke URI yang tidak punya rute
php artisan tinker --execute='echo app(\Illuminate\Contracts\Http\Kernel::class)->handle(\Illuminate\Http\Request::create("/tidak-ada"))->getStatusCode();'
text Keluaran
404

Kesalahan kedua adalah memanggil route() dengan nama yang tidak terdaftar. Panggilan itu melempar exception RouteNotFoundException dengan pesan Route [tidak-ada] not defined., dan perbaikannya adalah menyamakan nama pada pemanggilan dengan nama pada definisi rute. Kesalahan ketiga adalah perubahan rute yang tidak tampak karena cache rute aktif. Perintah php artisan route:cache yang dijalankan saat deployment menyimpan rute dalam satu berkas cache, sehingga perubahan pada routes/web.php hanya terlihat setelah php artisan route:clear dijalankan.

Ringkasan#

  • Rute didefinisikan pada routes/web.php dengan Route::get(), Route::post(), dan metode kata kerja HTTP lainnya, lalu diperiksa ulang melalui php artisan route:list.
  • Parameter rute di dalam kurung kurawal disuntikkan ke closure menurut urutan, dan formatnya dibatasi dengan whereAlpha(), whereNumber(), atau where().
  • Permintaan dengan URI yang tak dikenal dibalas 404, sedangkan metode HTTP yang tidak cocok dibalas 405.
  • Rute bernama yang ditetapkan name() memungkinkan URL dibangkitkan dengan helper route(), sehingga perubahan URI tidak merusak tautan.

Referensi#

  • Routing — Laravel — Dokumentasi resmi rute Laravel yang menjadi dasar pembahasan rute dasar, parameter, batasan, rute bernama, dan route:list pada topik ini.