Route Parameters
Lendly has 500 books. Writing 500 routes, one for /books/1, one for /books/2 and so on, is absurd. You want one route that means "/books/ followed by any id", with the id handed to your code. That is a route parameter.
The rule
Braces capture a segment; the closure receives it in order.
Route::get('/books/{id}', function (string $id) {
return "Book number {$id}";
});A visit to /books/42 runs the closure with $id = '42'.
With several parameters, they are passed in the order they appear in the URI. The variable names in the closure do not have to match:
Route::get('/members/{member}/loans/{loan}', function ($m, $l) {
return "Loan {$l} of member {$m}";
});Optional parameters use a ? in the URI and need a default value in the closure:
Route::get('/members/{name?}', function (?string $name = 'guest') {
return "Hello, {$name}";
});/members gives "Hello, guest", and /members/ana gives "Hello, ana".
Constraints limit what a parameter may be. If the value does not fit, the route does not match, and the visitor gets a 404:
Route::get('/books/{id}', fn ($id) => "Book {$id}")
->whereNumber('id');
Route::get('/genres/{slug}', fn ($slug) => $slug)
->where('slug', '[a-z-]+');Other helpers include whereAlpha, whereAlphaNumeric, whereUuid and whereIn('status', ['open', 'returned']).
By default a parameter matches anything except /.
The shortcut
Line the URI up against the closure's argument list and pair them left to right. The first brace goes to the first argument, the second to the second. Then add a constraint wherever a bad value would crash your code.
Match the pattern
/members/{member}/loans/{loan}fits.memberis7,loanis31.
The trap is an optional parameter without a default, such as function ($name) for {name?}. Visiting /members then fails because the closure has nothing to receive.
Drills
Answer fast — trust the rule.
For Route::get('/books/{id}', fn ($id) => $id), what does /books/58 return?
What does {name?} need in the closure?
A route has ->whereNumber('id'). What happens at /books/dune?
For /shelves/{shelf}/books/{book} and function ($a, $b), what is $b at /shelves/3/books/9?
Remember
- Braces capture a segment; the closure receives it in order.
- Pair braces with arguments left to right, and guard with
whereconstraints. - Trap: an optional parameter needs a default value.
