Routing Basics

A route is simply a mapping between a URL and the code that should run when a request hits that URL. Laravel's routing layer is deliberately expressive — most routes read almost like plain English — while still supporting everything a real application needs: parameters, constraints, naming, and more. This page covers the fundamentals; the next lesson builds on it with groups, resource routes, and model binding.

1. web.php vs api.php

Every new project ships with routes/web.php already wired up for browser-facing routes — these automatically get session state, cookie encryption, and CSRF protection applied via Laravel's default web middleware group. If you also work with routes/api.php, know that it's built for stateless routes instead: no sessions or CSRF, every route prefixed with /api automatically, and typically meant to be consumed by a JavaScript frontend or an external client rather than a browser navigating directly. This tutorial track focuses on web.php, since that's where the large majority of a typical application's routes live.

2. The HTTP Verb Methods

Routes are registered against the Route facade, with one method per HTTP verb:

MethodTypical use
Route::get()Retrieving a page or resource — the vast majority of routes in a typical app
Route::post()Submitting a form or creating a new resource
Route::put()Replacing an existing resource entirely
Route::patch()Partially updating an existing resource
Route::delete()Deleting a resource

3. Closures vs Controllers

The simplest possible route returns a response directly from a closure — handy for quick tests or genuinely trivial pages:

<?php
// routes/web.php
Route::get('/', function () {
    return view('welcome');
});

For anything beyond a trivial page, point the route at a controller method instead, using the [Controller::class, 'method'] array syntax:

Route::get('/users', [UserController::class, 'index']);

Controllers are covered in full later in this track, but in short: this tells Laravel "when someone requests GET /users, instantiate UserController and call its index() method."

4. Route Parameters

Segments of the URL can be captured as parameters by wrapping a name in curly braces. Laravel passes the matched value into your closure or controller method automatically:

Route::get('/users/{id}', function ($id) {
    return "User #" . $id;
});

A parameter can be made optional by appending a ? — in that case, give the matching function argument a default value too, since the parameter may not be present at all:

Route::get('/users/{id?}', function ($id = null) {
    return $id ? "User #" . $id : "No user specified";
});

5. Constraining Parameters with where()

By default a route parameter matches almost any character. Use where() to restrict it with a regular expression — useful for making sure, say, an {id} segment only ever matches digits:

Route::get('/users/{id}', [UserController::class, 'show'])
    ->where('id', '[0-9]+');

6. Naming Routes and the route() Helper

Giving a route a name lets you refer to it consistently everywhere else in your application — in Blade views, redirects, and elsewhere — without ever hardcoding its literal URL. If the URL ever changes, every reference built with the route() helper keeps working automatically:

Route::get('/users/{id}', [UserController::class, 'show'])
    ->name('users.show');

// building a URL to that route elsewhere in the app
$url = route('users.show', ['id' => 5]);
// => /users/5
Convention: Route names are commonly dot-namespaced by resource, like users.show, users.index, articles.edit — this reads naturally and avoids naming collisions as an app grows.

7. Listing All Registered Routes

Once a project has more than a handful of routes, it's easy to lose track of what's registered. Artisan can print every route Laravel currently knows about, straight from the terminal:

php artisan route:list

The output shows each route's HTTP verb, URI, name (if any), and the controller/action or closure it points to — an invaluable debugging tool when a request isn't reaching the code you expect.

Up next: Routing: Advanced covers grouping routes, resource routes, and one of Laravel's most convenient features — automatic route model binding.