A better way to register routes in Laravel
Let's take a look at how you can define routes to controllers in Laravel. By default you can do it like this:
Route::get('my-route', 'MyController@index');
This will look for the MyController
class in the App\Http\Controllers
namespace. This default namespace is set up in Laravel's RouteServiceProvider.
This was fine for a long time, but in modern Laravel apps (thanks for that PR, Jaanus Vapper) there's a cool new way to register routes. You can define them using a tuple. Let's see how that looks like:
Route::get('my-route', [\App\Http\Controllers\MyController::class, 'index']);
You can make it shorter by importing the namespace:
use App\Http\Controllers\MyController;
Route::get('my-route', [MyController::class, 'index']);
In a real-world route file You might end up with lots of use
statements, but a good IDE will just hide all of them.
In order to make tuple notation work you'll need to remove this namespace
call in the RouteServiceProvider
so Laravel won't prefix \App\Http\Controllers
to an already fully qualified controller class name.
Compared to using strings, defining a route using a tuple has two benefits:
- If you're using an IDE like PhpStorm you can now just click through the controller class name in your route files to go to the right controller.
- When refactoring the name or namespace of the controller the class names in your route file will change too.
You can use tuple notation when redirection using the action
method too.
namespace App\Http\Controllers;
class MyController
{
public function myMethod()
{
// do some work...
return redirect->action([MyOtherController::class, 'index']);
}
}
If you're using an invokable controller, you can define a route like this
use App\Http\Controllers\MyController;
Route::get('my-route', MyController::class);
At Spatie we're now using this tuple notation in all our current projects. I've also updated my blog to use them, here's the relevant commit.
In my opinion, tuple based routes should become the default in a future version of Laravel. There are only benefits and there's less magic involved (no need to prefix a string behind the scenes).
Do you like this notation? Let me know in the comments below.
What are your thoughts on "A better way to register routes in Laravel"?