Pendahuluan
Setelah berhasil menginstall Laravel, pertanyaan berikutnya adalah: bagaimana cara kerja URL di Laravel?
Ketika seseorang mengakses https://taskmanager.com/tasks, bagaimana Laravel tahu kode mana yang harus dijalankan? Inilah tugas Router — pengarah lalu lintas yang menentukan kode apa yang dipanggil untuk setiap URL.
Di artikel ini kamu akan memahami:
- Cara mendefinisikan route dasar
- Parameter URL dinamis
- Named routes dan URL generation
- Controller dan cara membuatnya
- Resource Controller untuk CRUD
- Route Group dan Middleware
Mari kita mulai dengan membuka file routes/web.php di proyek task-manager.
Routing Dasar
File routes/web.php adalah tempat kamu mendefinisikan semua URL yang bisa diakses oleh pengguna melalui browser.
<?php
// routes/web.php
use Illuminate\Support\Facades\Route;
// Route paling sederhana — tampilkan teks
Route::get('/hello', function () {
return 'Halo, dunia!';
});
// Tampilkan view Blade
Route::get('/', function () {
return view('welcome');
});
// Return JSON (cocok untuk testing)
Route::get('/info', function () {
return ['status' => 'ok', 'laravel' => app()->version()];
});
HTTP Methods yang Didukung
Laravel mendukung semua HTTP method:
Route::get('/tasks', function () { /* tampilkan daftar */ });
Route::post('/tasks', function () { /* simpan data baru */ });
Route::put('/tasks/{id}', function ($id) { /* update data */ });
Route::patch('/tasks/{id}', function ($id) { /* partial update */ });
Route::delete('/tasks/{id}', function ($id) { /* hapus data */ });
// Merespons semua method HTTP
Route::any('/webhook', function () { /* handle semua */ });
// Merespons beberapa method sekaligus
Route::match(['get', 'post'], '/contact', function () {
// handle GET (tampil form) dan POST (proses form)
});
Parameter URL
URL seringkali membutuhkan nilai dinamis, seperti ID artikel atau username pengguna.
Parameter Wajib
// {id} adalah parameter yang wajib ada
Route::get('/tasks/{id}', function (string $id) {
return "Menampilkan task #" . $id;
});
// Akses: /tasks/42 → "Menampilkan task #42"
// Akses: /tasks → 404 Not Found
Parameter Opsional
// {name?} adalah parameter opsional (ada tanda tanya)
Route::get('/user/{name?}', function (string $name = 'Tamu') {
return "Halo, " . $name . "!";
});
// Akses: /user/Budi → "Halo, Budi!"
// Akses: /user → "Halo, Tamu!"
Validasi Parameter dengan Regex
// Hanya menerima angka
Route::get('/tasks/{id}', function (string $id) {
return "Task #" . $id;
})->where('id', '[0-9]+');
// Hanya menerima huruf
Route::get('/user/{name}', function (string $name) {
return "User: " . $name;
})->where('name', '[A-Za-z]+');
// Menggunakan helper method
Route::get('/tasks/{id}', function ($id) {})->whereNumber('id');
Route::get('/user/{name}', function ($name) {})->whereAlpha('name');
Named Routes
Named routes memungkinkan kamu membuat URL menggunakan nama route, bukan string URL langsung. Ini sangat berguna agar jika URL berubah, kamu tidak perlu mengubah kode di banyak tempat.
// Beri nama pada route
Route::get('/tasks', [TaskController::class, 'index'])->name('tasks.index');
Route::get('/tasks/{id}', [TaskController::class, 'show'])->name('tasks.show');
Route::get('/tasks/create', [TaskController::class, 'create'])->name('tasks.create');
// Gunakan di Controller atau Blade
$url = route('tasks.index'); // http://localhost:8000/tasks
$url = route('tasks.show', ['id' => 42]); // http://localhost:8000/tasks/42
{{-- Di file Blade --}}
<a href="{{ route('tasks.index') }}">Daftar Task</a>
<a href="{{ route('tasks.show', ['id' => $task->id]) }}">Detail Task</a>
Controller
Sampai sini, kita masih menulis logika langsung di file route (closure). Untuk aplikasi sungguhan, ini tidak ideal. Controller memisahkan logika ke file tersendiri sehingga lebih terorganisir.
Membuat Controller
# Buat controller menggunakan Artisan
php artisan make:controller TaskController
# File dibuat di: app/Http/Controllers/TaskController.php
<?php
// app/Http/Controllers/TaskController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TaskController extends Controller
{
// Method index — tampilkan daftar task
public function index()
{
return view('tasks.index');
}
// Method show — tampilkan detail task
public function show(string $id)
{
return view('tasks.show', ['id' => $id]);
}
}
Menghubungkan Route ke Controller
<?php
// routes/web.php
use App\Http\Controllers\TaskController;
Route::get('/tasks', [TaskController::class, 'index'])->name('tasks.index');
Route::get('/tasks/{id}', [TaskController::class, 'show'])->name('tasks.show');
Sintaks [TaskController::class, 'index'] berarti “panggil method index dari class TaskController”.
Resource Controller — CRUD dalam Satu Perintah
Untuk operasi CRUD (Create, Read, Update, Delete), Laravel menyediakan Resource Controller yang secara otomatis membuat 7 method standar.
# Buat resource controller
php artisan make:controller TaskController --resource
# Untuk sekaligus dengan model:
php artisan make:controller TaskController --model=Task --resource
Resource Controller yang dibuat memiliki 7 method:
class TaskController extends Controller
{
// GET /tasks
public function index() { /* tampilkan semua task */ }
// GET /tasks/create
public function create() { /* tampilkan form buat task baru */ }
// POST /tasks
public function store(Request $request) { /* simpan task baru */ }
// GET /tasks/{task}
public function show(Task $task) { /* tampilkan detail task */ }
// GET /tasks/{task}/edit
public function edit(Task $task) { /* tampilkan form edit */ }
// PUT/PATCH /tasks/{task}
public function update(Request $request, Task $task) { /* update task */ }
// DELETE /tasks/{task}
public function destroy(Task $task) { /* hapus task */ }
}
Mendaftarkan Route Resource
Satu baris ini menggantikan 7 route sekaligus!
// routes/web.php
Route::resource('tasks', TaskController::class);
Jalankan php artisan route:list untuk melihat semua route yang dibuat:
GET /tasks → TaskController@index (tasks.index)
GET /tasks/create → TaskController@create (tasks.create)
POST /tasks → TaskController@store (tasks.store)
GET /tasks/{task} → TaskController@show (tasks.show)
GET /tasks/{task}/edit → TaskController@edit (tasks.edit)
PUT /tasks/{task} → TaskController@update (tasks.update)
DELETE /tasks/{task} → TaskController@destroy (tasks.destroy)
Membatasi Method Resource
Jika tidak membutuhkan semua 7 method:
// Hanya index, create, store, show
Route::resource('tasks', TaskController::class)->only(['index', 'create', 'store', 'show']);
// Semua kecuali create dan edit (cocok untuk API)
Route::resource('tasks', TaskController::class)->except(['create', 'edit']);
Single Action Controller
Untuk aksi yang sangat sederhana dan hanya punya satu method, gunakan Single Action Controller dengan method __invoke:
php artisan make:controller WelcomeController --invokable
class WelcomeController extends Controller
{
public function __invoke()
{
return view('welcome');
}
}
// Route yang lebih bersih
Route::get('/', WelcomeController::class);
Route Group
Route Group berguna untuk mengelompokkan route yang memiliki prefix, middleware, atau namespace yang sama.
Group dengan Prefix URL
// Semua route di dalam group ini akan memiliki prefix /admin
Route::prefix('admin')->group(function () {
Route::get('/dashboard', [AdminController::class, 'dashboard']); // /admin/dashboard
Route::get('/users', [AdminController::class, 'users']); // /admin/users
Route::resource('/posts', AdminPostController::class); // /admin/posts/...
});
Group dengan Middleware
// Semua route ini membutuhkan user yang sudah login
Route::middleware('auth')->group(function () {
Route::get('/profile', [ProfileController::class, 'show']);
Route::resource('tasks', TaskController::class);
});
// Middleware ganda
Route::middleware(['auth', 'verified'])->group(function () {
Route::get('/dashboard', [DashboardController::class, 'index']);
});
Kombinasi Prefix dan Middleware
Route::prefix('admin')
->middleware(['auth', 'admin'])
->name('admin.')
->group(function () {
Route::get('/dashboard', [AdminController::class, 'index'])->name('dashboard');
// URL: /admin/dashboard
// Name: admin.dashboard
});
Dependency Injection di Controller
Laravel memiliki Service Container yang secara otomatis meng-inject dependency ke controller. Ini sangat berguna untuk Request object.
use Illuminate\Http\Request;
class TaskController extends Controller
{
public function store(Request $request)
{
// $request otomatis di-inject oleh Laravel
$title = $request->input('title');
$description = $request->input('description', 'Tidak ada deskripsi');
// Cek apakah field ada
if ($request->has('due_date')) {
$dueDate = $request->input('due_date');
}
// Ambil semua input
$all = $request->all();
// Ambil hanya beberapa field
$data = $request->only(['title', 'description']);
return redirect()->route('tasks.index');
}
}
Melihat Semua Route
Gunakan Artisan untuk melihat daftar lengkap semua route yang terdaftar:
php artisan route:list
# Filter berdasarkan nama
php artisan route:list --name=tasks
# Filter berdasarkan method
php artisan route:list --method=GET
Output contoh:
GET / - welcome
GET /tasks tasks.index TaskController@index
GET /tasks/create tasks.create TaskController@create
POST /tasks tasks.store TaskController@store
GET /tasks/{task} tasks.show TaskController@show
GET /tasks/{task}/edit tasks.edit TaskController@edit
PUT|PATCH /tasks/{task} tasks.update TaskController@update
DELETE /tasks/{task} tasks.destroy TaskController@destroy
Troubleshooting: Error yang Sering Muncul
404 Not Found Meski Route Sudah Didefinisikan
Penyebab: Cache route lama masih aktif, atau penulisan URL tidak sesuai.
Solusi:
# Bersihkan cache route
php artisan route:clear
php artisan cache:clear
# Cek apakah route terdaftar
php artisan route:list | grep tasks
MethodNotAllowedHttpException — Method Not Allowed
Penyebab: Form HTML secara default hanya bisa mengirim GET dan POST. Untuk DELETE dan PUT, perlu spoofing menggunakan @method.
Solusi:
{{-- Form untuk DELETE --}}
<form action="{{ route('tasks.destroy', $task->id) }}" method="POST">
@csrf
@method('DELETE') {{-- Ini wajib! --}}
<button type="submit">Hapus</button>
</form>
{{-- Form untuk PUT (Edit) --}}
<form action="{{ route('tasks.update', $task->id) }}" method="POST">
@csrf
@method('PUT') {{-- Ini wajib! --}}
...
</form>
Target class [TaskController] does not exist
Penyebab: Lupa menambahkan use statement atau nama class salah.
Solusi:
<?php
// routes/web.php
// Pastikan menambahkan use statement
use App\Http\Controllers\TaskController;
// Bukan seperti ini (string):
Route::get('/tasks', 'TaskController@index'); // ❌ Laravel 8+ tidak pakai ini
// Tapi seperti ini:
Route::get('/tasks', [TaskController::class, 'index']); // ✅
Pertanyaan yang Sering Diajukan
Apa perbedaan routes/web.php dan routes/api.php?
web.php digunakan untuk halaman web yang memiliki session, cookies, dan CSRF protection — cocok untuk aplikasi web biasa. api.php digunakan untuk endpoint API yang stateless (tanpa session) — cocok untuk aplikasi mobile atau SPA. Kita akan membahas API routing lengkap di artikel REST API dengan Laravel Sanctum.
Kapan menggunakan Route::resource vs route manual?
Gunakan Route::resource jika kamu sedang membangun operasi CRUD standar untuk satu model (Task, Post, Product, dll). Gunakan route manual jika kamu butuh route yang tidak mengikuti pola CRUD, seperti /dashboard, /search, atau /export-pdf.
Apa itu middleware di Laravel?
Middleware adalah filter yang dieksekusi sebelum request sampai ke controller. Contoh: middleware auth akan redirect ke halaman login jika user belum login. Middleware throttle membatasi jumlah request per menit. Kita akan belajar lebih dalam tentang middleware di artikel Authentication di Laravel.
Kesimpulan
Kita sudah menguasai routing dan controller — tulang punggung setiap aplikasi Laravel! Berikut yang sudah kita pelajari:
- Routing dasar dengan berbagai HTTP method
- Parameter URL yang wajib dan opsional
- Named routes untuk URL generation yang fleksibel
- Controller untuk memisahkan logika dari route
- Resource Controller yang menghasilkan 7 route CRUD sekaligus
- Route Group untuk mengorganisir route dengan prefix dan middleware
Di artikel berikutnya, kita masuk ke Blade Template Engine — cara membuat tampilan yang dinamis dan cantik untuk aplikasi Task Manager kita.
Kamu sudah semakin dekat dengan menjadi Laravel developer yang solid. Terus semangat! 🎯