When it comes to the backend, developers eventually encounter routes. Routes can be considered the backbone of the backend since every request the server receives is redirected to a controller through a routing list that maps requests to controllers or actions.

Laravel hides many implementation details for us and comes with a lot of syntactic sugar to help both new and experienced developers develop their web applications.

Let’s take a close look at how to manage routes in Laravel.

Backend Routing and Cross-Site Scripting in Laravel

On a server, there exist both public and private routes. Public routes can be a cause of concern due to the possibility for cross-site scripting (XSS), a type of injection attack that can leave you and your users vulnerable to malicious actors.

The problem is that a user can be redirected from a route that doesn’t require a session token to one that does — and they’ll still have access without the token.

Dive into the ‘backbone of the backend’ in this guide to Lavavel Routing 🚀Click to Tweet

The simplest way to solve this issue is to enforce a new HTTP header, adding “referrer” to the route to mitigate this scenario:

'main' => [
  'path' => '/main',
  'referrer' => 'required,refresh-empty',
  'target' => Controller\DashboardController::class . '::mainAction'

Laravel Basic Routing

In Laravel, routes allow users to route the appropriate request to the desired controller. The most basic Laravel Route accepts a Uniform Asset Identifier (your route path) and a closure which can be both a function or a class.

In Laravel, routes are created inside the web.php and api.php files. Laravel comes with two routes by default: one for the WEB and one for the API.

These routes reside in the routes/ folder, but they are loaded in the Providers/RouteServiceProvider.php.

A command line showing showing the default state of the Laravel's route service provider.
Default state of Laravel’s route service provider.

Instead of doing this, we can load the routes directly inside RouteServiceProvider.php, skipping the routes/ folder altogether.

A command line window showing the loading of Laravel routes directly in the provider.
Loading Laravel routes directly in the provider.


When we define a route, we’ll usually want to redirect the user that accesses it, and the reasons for this vary a lot. It may be because it’s a deprecated route and we have changed the backend or the server, or it may be because we want to install two-factor authentication (2FA), and so on.

Laravel has an easy way of doing this. Thanks to the framework’s simplicity, we can use the redirect method on the Route facade, which accepts the entry route and the route to be redirected to.

Optionally, we can give the status code for the redirect as the third parameter. The permanentRedirect method will do the same as the redirect method, except it will always return a 301 status code:

// Simple redirect
Route::redirect("/class", "/myClass");

// Redirect with custom status
Route::redirect("/home", "/office", 305);

// Route redirect with 301 status code
Route::permanentRedirect("/home", "office");

Inside the redirect routes we are forbidden to use the “destination” and “status” keywords as parameters as they are reserved by Laravel.

// Illegal to use
Route::redirect("/home", "/office/{status}");


Views are the .blade.php files that we use to render the frontend of our Laravel application. It uses the blade templating engine, and it is the default way to build a full-stack application using only Laravel.

If we want our route to return a view, we can simply use the view method on the Route facade. It accepts a route parameter, a view name, and an optional array of values to be passed to the view.

// When the user accesses my-domain.com/homepage
// the homepage.blade.php file will be rendered
Route::view("/homepage", "homepage");

Let’s assume our view wants to say “Hello, {name}” by passing an optional array with that parameter. We can do just that with the following code (if the missing parameter is required in the view, the request will fail and throw an error):

Route::view('/homepage', 'homepage', ['name' => "Kinsta"]);

Route List

As your application grows in size, so will the number of requests that need to be routed. And with a great volume of information can come great confusion.

This is where the artisan route:list command can help us. It provides an overview of all the routes that are defined in the application, their middlewares, and controllers.

php artisan route:list

It will display a list of all routes without the middlewares. For this, we have to use the -v flag:

php artisan route:list -v

In a situation where you may be using domain-driven design where your routes have specific names in their paths, you can make use of the filtering capabilities of this command like so:

php artisan route:list –path=api/account

This will show only the routes that start with api/account.

On the other hand, we can instruct Laravel to exclude or include third-party defined routes by using the –except-vendor or –only-vendor options.

Route Parameters

Sometimes you might need to capture segments of the URI with the route, like a user ID or token. We can do this by defining a route parameter, which is always encased within curly braces ({}) and should only consist of alphabetic characters.

If our routes have dependencies inside their callbacks, the Laravel service container will automatically inject them:

use Illuminate\Http\Request;
use Controllers/DashboardController;
Route::post('/dashboard/{id}, function (Request $request, string $id) {
  return 'User:' . $id;
Route::get('/dashboard/{id}, DashboardController.php);

Required Parameters

Laravel’s required parameters are parameters in routes that we aren’t allowed to skip when we make a call. Otherwise, an error will be thrown:

Route::post("/gdpr/{userId}", GetGdprDataController.php");

Now inside the GetGdprDataController.php we will have direct access to the $userId parameter.

public function __invoke(int $userId) {
  // Use the userId that we received…

A route can take any numbers of parameters. They are injected in the route callbacks/controllers based on the order in which they’re listed:

 // api.php
Route::post('/gdpr/{userId}/{userName}/{userAge}', GetGdprDataController.php);
// GetGdprDataController.php
public function __invoke(int $userId, string $userName, int $userAge) {
  // Use the parameters…

Optional Parameters

In a situation where we want to do something on a route when only a parameter is present and nothing else, all without affecting the entire application, we can add an optional parameter. These optional parameters are denoted by the ? appended to them:

 Route::get('/user/{age?}', function (int $age = null) {
  if (!$age) Log::info("User doesn't have age set");
  else Log::info("User's age is " . $age);
Route::get('/user/{name?}', function (int $name = "John Doe") {
  Log::info("User's name is " . $name);

Route Wildcard

Laravel provides a way for us to filter what our optional or required parameters should look like.

Say we want a string of a user ID. We can validate it like so on the route level using the where method.

The where method accepts the name of the parameter and the regex rule that will be applied on the validation. By default, it takes the first parameter, but if we have many, we can pass an array with the name of the parameter as the key and the rule as the value, and Laravel will parse them all for us:

Route::get('/user/{age}', function (int $age) {
}->where('age', '[0-9]+');
Route::get('/user/{age}', function (int $age) {
Route::get('/user/{age}/{name}', function (int $age, string $name) {
}->where(['age' => '[0-9]+', 'name' => '[a-z][A-z]+');

We can take this a step further and apply validation on all the routes in our application by using the pattern method on the Route facade:

 Route::pattern('id', '[0-9]+');

This will valide every id parameter with this regex expression. And once we define it, it will be automatically applied to all routes using that parameter name.

As we can see, Laravel is using the / character as a separator in the path. If we want to use it in the path, we have to explicitly allow it to be part of our placeholder using a where regex.

 Route::get('/find/{query}', function ($query) {
})->where('query', , '.*');

The only downside is that it will be supported only in the last route segment.

Named Routes

As the name suggests, we can name routes, which makes it convenient to generate URLs or redirect for specific routes.

How To Create Named Routes

A simple way to create a named route is provided by the name method chained on the Route facade. Each route’s name should be unique:

 Route::get('/', function () {

Route Groups

Route groups allow you to share route attributes like middlewares across a large number of routes without needing to re-define it on each and every route.


Assigning a middleware to all routes we have allows us to combine them in a group, first by using the group method. One thing to consider is that the middlewares are executed in the order in which they are applied to the group:

 Route:middleware(['AuthMiddleware', 'SessionMiddleware'])->group(function () {
  Route::get('/', function() {} );
  Route::post('/upload-picture', function () {} );


When a group utilizes the same controller, we can use the controller method to define the common controller for all the routes within that group. Now we have to specify the method that the route will call.

 Route::controller(UserController::class)->group(function () {
  Route::get('/orders/{userId}', 'getOrders');
  Route::post('/order/{id}', 'postOrder');

Subdomain Routing

A subdomain name is a piece of additional information added to the beginning of a website’s domain name. This allows websites to separate and organize their content for specific functions, such as online stores, blogs, presentations, and so on from the rest of the website.

Our routes can be used to handle subdomain routing. We can catch the domain and a portion of the subdomain for usage in our controller and route. With the help of the domain method on the Route facade, we can group our routes under a single domain:

 Route::domain('{store}.enterprise.com')->group(function() {
  Route::get('order/{id}', function (Account $account, string $id) {
    // Your Code

Prefixes and Name Prefixes

Whenever we have a group of routes, instead of modifying them one by one, we can make use of the extra utilities that Laravel provides, such as prefix and name on the Route facade.

The prefix method can be used to prefix each route in the group with a given URI, and the name method can be used to prefix each route name with a given string.

This allows us to create new things like admin routes without being required to modify each and every name or prefix to identify them:

 Route::name('admin.")->group(function() {
  Route::prefix("admin")->group(function() {

Now the URIs for these routes will be admin/get, admin/put, admin/post, and the names admin.get, admin.put, and admin.post.

Route Caching

When deploying the application to production servers, a good Laravel developer will take advantage of Laravel’s route cache.

What Is Route Caching?

Route caching decreases the amount of time it takes to register all the application routes.

Running php artisan route:cache an instance of Illuminate/Routing/RouteCollection is generated, and after being encoded, the serialized output is written to bootstrap/cache.routes.php.

Now any other request will load this cache file if it exists. Therefore, our application no longer has to parse and convert entries from the route file into Illuminate/Routing/Route objects in Illuminate/Routing/RouteCollection.

Why It’s Important To Use Route Caching

By not using the route caching feature that Laravel provides, your application risks running more slowly than it could be, which could in turn decrease sales, user retention, and trust in your brand.

Depending on the scale of your project and how many routes there are, running a simple route caching command can speed up your application by anywhere from 130% to 500% — a massive gain for nearly no effort.


Routing is the backbone of backend development. The Laravel framework excels at this by providing a verbose way of defining and managing routes.Get comfortable with Laravel routing in this thorough guide 🛠Click to Tweet

Development can indeed be accessible for everyone and help speed up an application just by virtue of it being built in Laravel.

What other tricks and tips have you encountered regarding Laravel routes? Let us know in the comments section!

Get all your applications, databases and WordPress sites online and under one roof. Our feature-packed, high-performance cloud platform includes:

  • Easy setup and management in the MyKinsta dashboard
  • 24/7 expert support
  • The best Google Cloud Platform hardware and network, powered by Kubernetes for maximum scalability
  • An enterprise-level Cloudflare integration for speed and security
  • Global audience reach with up to 35 data centers and 275+ PoPs worldwide

Test it yourself with $20 off your first month of Application Hosting or Database Hosting. Explore our plans or talk to sales to find your best fit.

Source link