Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Routing  ›  Lesson

Route Parameters

Route parameters 12 minCurly-brace segments in a URI capture values that are passed to the route's action in order, optional ones need a ? and a default, and where constraints limit what they match.

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.

Resolving /members/7/loans/31Step 1 of 4
  1. Match the pattern

    /members/{member}/loans/{loan} fits. member is 7, loan is 31.

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.

quick drill

For Route::get('/books/{id}', fn ($id) => $id), what does /books/58 return?

quick drill

What does {name?} need in the closure?

quick drill

A route has ->whereNumber('id'). What happens at /books/dune?

quick drill

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 where constraints.
  • Trap: an optional parameter needs a default value.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainOne route, many books

Lendly needs /books/{id} for any book and /members/{name?} that shows a default guest page when no name is given. Write both routes, explain how values reach the closure, and add a constraint so /books/abc does not match.