The different ways to do routing in Laravel
Tags: php, laravel, routing
Published: 2021-09-15 09:41:01

---
title: The different ways to do routing in Laravel
published: true
date: 2021-06-03 13:42:01 UTC
tags: php, laravel, routing
canonical_url: https://dberri.com/the-different-ways-to-do-routing-in-laravel
---

Routing in Laravel is very flexible. You can define the routes to your app in so many ways, with so many modifiers, each with a different purpose or better suited to a specific use case. Today, I want to show you a few ways that helped me and that I use very frequently while working with Laravel.

The most basic one, is the first one shown in the documentation:

```php
use Illuminate\Support\Facades\Route;

Route::get('/greeting', function () {
    return 'Hello World';
});
```

This uses a closure and means that when a user hits navigates to `[your app host]/greeting` they will be greeted with a simple "Hello World" string. Technically, you can implement your entire application in this closure. Nothing will stop you if you try to add all your bussiness logic in there, but of course that's not very effective and if you have more routes it becomes very ugly.

When you just create a new Laravel application, it already comes with one basic route defined for `/` which looks like this:

```php
use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    return view('welcome');
});
```

This is a more elaborate version of the first one, but in this case, it is going to return a view. This view is a Blade file located in `resources/views` which is named `welcome.blade.php`. So, now you can start composing views using blade and if there's not much going on in your view (e.g. it's a static page) you don't need to create a controller just to return a view.

Speaking of controllers, there are a few ways you can point your route to a controller or controller method. The default way that appears in the documentation looks like this:

```php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;

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

When a request hits `/user` the method "index" in the UserController class will be called. Previously, I used to define routes with a different syntax (which as far as I know is still valid and working in Laravel 8:

```php
use Illuminate\Support\Facades\Route;

Route::get('/user', 'UserController@index');
```

Notice that it's the same controller and method, but instead of an array, you pass a string declaring the controller and method separated by a @ symbol. Another thing you'll notice is that we don't need the `use` statement for this class because Laravel will automatically try to find that the UserController class in the `App\Http\Controllers` namespace.  Even though this works the same way as the previous example, I prefer the previous one because the it comes with some IDE niceties, like clicking on a class and navigating to its definition, or if you move the class file to another directory, it will warn you the `use` statement is not valid anymore.

Just a quick and related note, you can do the same with model relationships:

```php
class User {
	public function books() {
    	return $this->hasMany('Book');
    }
}

use App\Book;

class User {
	public function books() {
    	return $this->hasMany(Book::class);
    }
}
```

## Invocable controllers

Now, if your controller is a little complex and you use it for a single action with the `__invoke` method, you don't need to pass an array with controller and method to the route declaration, you can just pass the class as an argument, like this:

```php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;

Route::get('/user', UserController::class);
```

## Resource routes

You can also do a similar route declaration with resource controllers. This type of controller is that classic "CRUD" class, where you have `index`, `show`, `create`, `store`, `edit`, `update`, and `destroy` methods. Then you can define the route to this controller like this:

```php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;

Route::resource('users', UserController::class);
```

This will create a route for each of the controller methods and will name them, just like if you had created them manually following this pattern:

```php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;

Route::get('/users', [UserController::class, 'index'])->name('users.index');
Route::get('/users/{user}', [UserController::class, 'show'])->name('users.show');
Route::get('/users/create', [UserController::class, 'create'])->name('users.create');
Route::post('/users', [UserController::class, 'store')->name('users.store');
Route::get('/users/{user}/edit', [UserController::class, 'edit'])->name('users.edit');
Route::patch('/users/{user}', [UserController::class, 'update'])->name('users.update');
Route::delete('/users/{user}', [UserController::class, 'destroy'])->name('users.destroy');
```

And if you don't want a few of those routes you can tell the resource method which ones you don't need:

```php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;

Route::resource('users', UserController::class)->except(['edit', 'udpate']);
```

Or the other way around, if you only need a few routes:

```php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;

Route::resource('users', UserController::class)->only(['index', 'show']);
```

And finally, if you are developing an API, you probably don't need the `create` and `edit` routes which usually navigate the user to a form. If that's the case, you can define the routes like this:

```php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;

Route::apiResource('users', UserController::class);
```

There is also a plural form of each one of these two methods, if you want to define multiple resource controllers:

```php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;
use App\Http\Controllers\BookController;

Route::resources([
	'users' => UserController::class
	'books' => BookController::class
]);

// or

Route::apiResources([
	'users' => UserController::class
	'books' => BookController::class
]);
```

One last case we can cover is nested resources. For example, if you want to update a specific book of a specific user, you could define the route as:

```php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserBookController;

Route::update('/users/{user}/books/{book}', [UserBookController::class, 'update']);
```

Or, using the resource syntax:

```php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserBookController;

Route::resource('users.books', UserBookController::class);
```

Much cleaner!

And that's it! I mean, there is a lot more to cover like middlewares, route grouping,  namespaces, Route Model Binding, rate limiting, and so on. But I'll write more about those in the future. If you're curious and want to dig deeper, I suggest you dive into [Laravel's documentation](https://laravel.com/docs/8.x/routing). See you next time 👋