Semakin besar aplikasi, semakin banyak route yang terdaftar — dan semakin mudah kita kehilangan jejak method mana yang menangani URI tertentu, middleware apa yang menempel, atau mengapa satu URL menjawab 404 padahal menurut kita sudah didaftarkan. Laravel menyediakan php artisan route:list sebagai jendela resmi ke dalam router: perintah ini membaca route yang benar-benar terdaftar, bukan yang kita kira terdaftar. Chapter penutup section ini membahas cara membaca keluarannya, memfilter dan mengubah formatnya, lalu memakainya untuk men-debug tiga kasus klasik: method tidak cocok, parameter menelan segmen statis, dan constraint yang menolak nilai. Seluruh opsi perintahnya juga tercantum di dokumentasi routing
.
Membaca Kolom route:list #
Kita pakai set route berikut di routes/web.php — perhatikan bahwa versi ini sudah memakai whereNumber(), dan kita akan memutar ulang bug-nya sebentar lagi di bagian debugging:
<?php
use App\Http\Controllers\TugasController;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return 'Beranda';
})->name('beranda');
Route::controller(TugasController::class)->group(function () {
Route::get('/tugas', 'index')->name('tugas.index');
Route::post('/tugas', 'store')->name('tugas.store');
});
Route::get('/tugas/{id}', function (string $id) {
return "Tugas nomor {$id}";
})->whereNumber('id')->name('tugas.show');
Route::get('/tugas/arsip', function () {
return 'Halaman arsip';
})->name('tugas.arsip');
Route::middleware('auth')->group(function () {
Route::get('/profil', function () {
return 'Profil pengguna';
})->name('profil');
});Jalankan perintah dasarnya tanpa opsi apa pun:
php artisan route:listOutput yang Dihasilkan:
GET|HEAD / ..................................... beranda › routes/web.php:6
GET|HEAD profil ................................ profil › routes/web.php:24
GET|HEAD sanctum/csrf-cookie sanctum.csrf-cookie › Laravel\Sanctum › CsrfC…
GET|HEAD storage/{path} storage.local › vendor/laravel/framework/src/Illum…
PUT storage/{path} storage.local.upload › vendor/laravel/framework/sr…
GET|HEAD tugas ........................ tugas.index › TugasController@index
POST tugas ........................ tugas.store › TugasController@store
GET|HEAD tugas/arsip ...................... tugas.arsip › routes/web.php:19
GET|HEAD tugas/{id} ........................ tugas.show › routes/web.php:15
GET|HEAD up vendor/laravel/framework/src/Illuminate/Foundation/Configurati…
Showing [10] routesSetiap baris terdiri dari empat kolom informasi:
| Kolom | Contoh | Arti |
|---|---|---|
| Method | GET|HEAD | HTTP method yang cocok; HEAD otomatis ikut GET |
| URI | tugas/{id} | Pola path yang didaftarkan |
| Nama | tugas.show | Nama route untuk helper route() |
| Action | TugasController@index / routes/web.php:19 | Handler yang dijalankan beserta lokasinya |
Tiga route berasal dari luar kode kita: sanctum/csrf-cookie milik paket Sanctum, storage/{path} dari framework untuk file publik, dan up sebagai health check bawaan. Route sendiri ditampilkan berurutan menurut URI — ingat bahwa urutan ini bukan urutan pencocokan, yang tetap mengikuti urutan pendaftaran di berkas.
Menyembunyikan Route Vendor dan Melihat Middleware #
Flag --except-vendor menyembunyikan route bawaan paket agar daftarnya fokus pada route milik kita:
php artisan route:list --except-vendorOutput yang Dihasilkan:
GET|HEAD / .................................... beranda › routes/web.php:6
GET|HEAD profil ............................... profil › routes/web.php:24
GET|HEAD tugas ....................... tugas.index › TugasController@index
POST tugas ....................... tugas.store › TugasController@store
GET|HEAD tugas/arsip ..................... tugas.arsip › routes/web.php:19
GET|HEAD tugas/{id} ....................... tugas.show › routes/web.php:15
Showing [6] routesKolom middleware tidak tampil secara default. Tambahkan flag -v dan setiap route menampilkan tumpukan middleware-nya:
php artisan route:list -v --except-vendorOutput yang Dihasilkan:
GET|HEAD / .................................... beranda › routes/web.php:6
⇂ web
GET|HEAD profil ............................... profil › routes/web.php:24
⇂ web
⇂ Illuminate\Auth\Middleware\Authenticate
GET|HEAD tugas ....................... tugas.index › TugasController@index
⇂ web
POST tugas ....................... tugas.store › TugasController@store
⇂ web
GET|HEAD tugas/arsip ..................... tugas.arsip › routes/web.php:19
⇂ web
GET|HEAD tugas/{id} ....................... tugas.show › routes/web.php:15
⇂ web
Showing [6] routesTerlihat semua route membawa group web — session, cookie, dan CSRF — sedangkan /profil ditambah Authenticate dari group auth yang kita pasang. Pencarian “kenapa route ini diminta login” hampir selalu berakhir di output ini.
Memfilter dan Mengubah Format Keluaran #
Saat daftar route membludak, dua flag filter menyelamatkan: --path menyaring menurut awalan URI, dan --name menyaring menurut nama route:
php artisan route:list --path=tugas --except-vendor
php artisan route:list --name=tugas.show --except-vendorOutput yang Dihasilkan:
GET|HEAD tugas ....................... tugas.index › TugasController@index
POST tugas ....................... tugas.store › TugasController@store
GET|HEAD tugas/arsip ..................... tugas.arsip › routes/web.php:19
GET|HEAD tugas/{id} ....................... tugas.show › routes/web.php:15
Showing [4] routes
GET|HEAD tugas/{id} ................... tugas.show › routes/web.php:15
Showing [1] routesUntuk diproses skrip atau alat lain, flag --json mengubah keluaran menjadi JSON berisi seluruh detail setiap route:
php artisan route:list --json --path=profil --except-vendorOutput yang Dihasilkan:
[{"domain":null,"method":"GET|HEAD","uri":"profil","name":"profil","action":"Closure","middleware":["web","Illuminate\\Auth\\Middleware\\Authenticate"],"path":"routes\/web.php:24"}]Setiap objek memuat domain, method, URI, nama, action, middleware, hingga lokasi baris pendaftaran. Perhatikan "path": null pada route controller — lokasi baris hanya tersedia untuk handler closure.
Debugging Route yang Tidak Cocok #
Sekarang bagian yang paling berguna. Bayangkan versi awal route tugas.show belum memakai whereNumber('id'), lalu kita uji empat request dengan runner dari chapter sebelumnya:
Output yang Dihasilkan:
GET /tugas/5 → HTTP 200 | Tugas nomor 5
GET /tugas/arsip → HTTP 200 | Tugas nomor arsip
GET /tugas/abc → HTTP 200 | Tugas nomor abc
PUT /tugas → HTTP 405 | (halaman error HTML)Dua bug dan satu gejala tersembunyi di sana. Baris kedua adalah bug shadowing: route /tugas/{id} didaftarkan lebih dulu sehingga segmen statis arsip tertangkap sebagai nilai $id — padahal route /tugas/arsip yang kita maksud juga terdaftar. Baris ketiga memperlihatkan parameter tanpa constraint menerima nilai apa pun. Baris keempat adalah 405 Method Not Allowed: route:list di atas menunjukkan hanya GET|HEAD dan POST yang terdaftar untuk URI tugas, sehingga PUT memang tidak akan pernah cocok — perbaikannya adalah mendaftarkan Route::put().
Setelah whereNumber('id') dipasang kembali, uji yang sama menghasilkan:
GET /tugas/5 → HTTP 200 | Tugas nomor 5
GET /tugas/arsip → HTTP 200 | Halaman arsip
GET /tugas/abc → HTTP 404 | (halaman error HTML)
PUT /tugas → HTTP 405 | (halaman error HTML)Angka lolos constraint, /tugas/arsip jatuh ke route statis karena pola tugas/(\d+) menolaknya, dan /tugas/abc dijawab 404 karena tidak ada route yang menerima segmen non-numik. Sebagai rangkuman pola diagnosis:
| Gejala | Penyebab umum | Yang dilihat di route:list |
|---|---|---|
| 404 padahal URI terlihat terdaftar | Constraint menolak nilai parameter | Kolom URI dengan placeholder seperti {id} |
| 405 Method Not Allowed | HTTP method belum didaftarkan | Kolom Method yang tidak memuat verb tersebut |
| Handler “nyasar” menerima segmen statis | Route parameter terdaftar sebelum route statis | Urutan pendaftaran di berkas route |
| Route baru tidak muncul | Route ter-cache dari deployment lama | Daftar yang tidak berubah setelah edit |
Dengan route:list, filter, dan pola diagnosis di atas, kita memiliki cara sistematis memverifikasi router yang selama ini kita rakit dari route dasar, parameter, binding, sampai group. Section Routing dan Request telah lengkap: request berikutnya menuntut penulisan ulang logika ke controller — struktur yang lebih rapi untuk handler yang terus bertambah.