DEV Community

Raheel Shan
Raheel Shan

Posted on • Originally published at raheelshan.com

8 Powerful Laravel Routing Features Every Developer Should Know

Routing is a critical part of any Laravel application. It defines how your application responds to incoming requests. Laravel offers a robust and flexible routing system that supports a wide range of routing styles and features. This article breaks down Laravel routes into eight main categories, providing clear explanations and practical examples for each as well as some tips.

1. HTTP Verb Routes

Laravel supports all major HTTP verbs through dedicated route methods:

Route::get('/users', $callback);
Route::post('/users', $callback);
Route::put('/users/{id}', $callback);
Route::patch('/users/{id}', $callback);
Route::delete('/users/{id}', $callback);
Route::options('/users', $callback);
Enter fullscreen mode Exit fullscreen mode

There are some other methods to define combination of multiple verbs:

Route::match(['get','post'],'/users/{id}', function ($id) {
    // handling logic
});

Route::any('/users', function () {
    // handling logic
});
Enter fullscreen mode Exit fullscreen mode

Tip: Avoid using Route::any() unless necessary. Instead, explicitly define the accepted methods for better API clarity and security.

2. Redirect Routes

When you need to redirect a route, Laravel offers simple methods:

Route::redirect('/here', '/there');
Route::permanentRedirect('/old', '/new');
Enter fullscreen mode Exit fullscreen mode

Although both seem similar but they have a few differences. Lets see the use case to better understand.

Route::redirect()

Route::redirect() generates the status code 302 but you can optionally pass third parameter to override.

Route::redirect('/here', '/there', 301); 
// generate status code 301 instead of default 302
Enter fullscreen mode Exit fullscreen mode

Use Route::redirect() when the redirection might change in the future. For example you're running a sale on a new page only for this month.

Route::redirect('/sale', '/special-offer', 302);
Route::permanentRedirect()
Enter fullscreen mode Exit fullscreen mode

Route::permanentRedirect() always return status code 301. You can use it when you're sure the old URL should never be used again. This is ideal for maintaining SEO rankings and updating external links to the new URL. For example you've renamed a blog post, and you want to preserve SEO juice:

Route::permanentRedirect('/blog/old-title', '/blog/new-title');
Enter fullscreen mode Exit fullscreen mode

3. MVC Routes

Laravel makes it easy to create routes that link directly to views, controllers, or models:

Route::view()

You can use it when you have static pages with no or very less data. However, avoid using it for views with complex logic or if the data needs processing.

// Directly return a view
Route::view('/welcome', 'welcome', ['name' => 'John']);
Enter fullscreen mode Exit fullscreen mode

Tip: If you are using Laravel with any frontend library or framework (eg. react, vue, angular etc) it is best to use since most of the data fetching and rendering is done by js.

Route::model()

You can use it when you need to expose model data. Instead of going through controller layer you can directly bind model with route.

// Implicit model binding
Route::get('/users/{user}', function (User $user) {
    return $user;
});
Enter fullscreen mode Exit fullscreen mode

Tip: When using APIs, instead of returning the raw model directly, wrap it in a resource or resource collection to control the output structure and avoid exposing table structure.

Route::controller()

This one is ideal for grouping related routes and keeping your web.php or api.php file clean.

// Cleaner and consistent
Route::controller(UserController::class)->group(function () {
    Route::get('/users', 'index'); // GET /users -> index method
    Route::post('/users', 'store'); // POST /users -> store method
    Route::get('/users/{user}', 'show'); // GET /users/{user} -> show method
});
Enter fullscreen mode Exit fullscreen mode

Tip: When using Route::controller(), method names should match HTTP verbs (index, store, update, destroy, show) to keep things intuitive.

4. Domain Routes

For multi-domain applications, Laravel supports domain-specific routing:

Route::domain('client.mysite.com')->group(function () {
    Route::get('/dashboard', function () {
        return 'Client Dashboard';
    });
});

Route::domain('admin.mysite.com')->group(function () {
    Route::get('/dashboard', function () {
        return 'Admin Dashboard';
    });
});
Route::domain('mysite.com')->group(function () {
    Route::get('/', function () {
        return view('home');
    });
});
Enter fullscreen mode Exit fullscreen mode

Tip: For subdomain routing it is better to create separate files like client.php and admin.php for maintainability.

5. Fallback Route

To handle undefined routes gracefully, use Route::fallback():

Route::fallback(function () {
    return response('Page Not Found', 404);
});
Enter fullscreen mode Exit fullscreen mode

This is particularly useful for building custom 404 pages.

Tip: Your Laravel application must have this to avoid any broken links.

6. Information Routes

You can get detailed information about the current route using these methods:

$current = Route::current(); // Illuminate\Routing\Route
$name = Route::currentRouteName(); // string
$action = Route::currentRouteAction(); // string
Enter fullscreen mode Exit fullscreen mode

7. Route Groups

There are 3 methods available that are used with Route::group() method. Lets explore them one by one.

Route::middleware()

To assign multiple a group of routes you can use Route::middleware() method.

Route::middleware(['auth', 'verified'])->group(function () {
    // all protected routes
});
Enter fullscreen mode Exit fullscreen mode

Route::prefix()

This one adds a prefix to all routes within a group.

Route::prefix('admin')->group(function () {
    Route::get('/dashboard', function () {
        // Matches The "/admin/dashboard" URL
    });
    Route::get('/users', function () {
        // Matches The "/admin/users" URL
    });
    Route::get('/orders', function () {
        // Matches The "/admin/orders" URL
    });
});
Enter fullscreen mode Exit fullscreen mode

Route::name()

This adds name prefix to all routes within a group.

Route::name('admin.')->group(function () {
    Route::get('/dashboard', $callback)->name('dashboard'); // admin.dashboard
    Route::get('/users', $callback)->name('users'); // admin.users
});
Enter fullscreen mode Exit fullscreen mode

Tip: You can go as deep as possible to construct urls and names using Route::prefix() and Route::name(). See the example below.

// Url generation example
Route::prefix('v1')->group(function () {
    Route::prefix('admin')->group(function () {
      Route::prefix('stores')->group(function () {  
         Route::get('/products',$callback); // v1/admin/stores/products
         Route::get('/brands', $callback); // v1/admin/stores/brands
         Route::get('/categories', $callback); // v1/admin/stores/categorie
      });
   });

   Route::prefix('web')->group(function () {
      Route::get('/dashboard',$callback); // v1/web/dashboard
      Route::get('/users', $callback); // v1/web/users
      Route::get('/orders', $callback);// v1/web/orders
   });
});
// name generation example
Route::name('v1')->group(function () {
  Route::name('admin')->group(function () {
    Route::name('stores')->group(function () {
       Route::get('/products',$callback)->name('products'); // v1.admin.stores.products
       Route::get('/brands', $callback)->name('brands'); // v1.admin.stores.brands
       Route::get('/categories', $callback)->name('categories'); // v1.admin.stores.categories
    });
  });

   Route::name('web')->group(function () {
      Route::get('/dashboard',$callback)->name('dashboard'); // v1.web.dashboard
      Route::get('/users', $callback)->name('users'); // v1.web.users
      Route::get('/orders', $callback)->name('orders');// v1.web.orders
   });
});
Enter fullscreen mode Exit fullscreen mode

8. Additional Routes

There are a few more routes useful in some cases.

Route::pattern()

This globally enforces a regex pattern for route parameters.

// AppServiceProvider

public function boot(): void
{
    Route::pattern('id', '[0-9]+');
}
Enter fullscreen mode Exit fullscreen mode

Once the pattern has been applied you should be at ease now that it will only allow numeric ids.

Route::get('/user/{id}', function (string $id) {
    // Only executed if {id} is numeric...
});
Enter fullscreen mode Exit fullscreen mode

Route::bind()

You can use this method in boot method of AppServiceProvider.php to customize logic of parameter binding for example you want user to always have email as value.

Route::bind('user', function (string $value) {
    return User::where('email', $value)->firstOrFail();
});
Enter fullscreen mode Exit fullscreen mode

Alternatively you can use Route::model() to explicitly bind parameter with model in boot method of AppServiceProvider.php

Route::model('user', User::class);
Enter fullscreen mode Exit fullscreen mode

Tip: Using Route::model() in combination with Route::pattern() can lead to cleaner and safer routing.

Conclusion

Mastering Laravel’s routing system can significantly improve your application’s architecture and maintainability. Use the appropriate routing methods for each scenario, and leverage route groups, patterns, and bindings to keep your code clean and concise. Whether you’re building a simple site or a complex application, Laravel has you covered.

Top comments (0)