https://laraveldaily.com/storage/322/Wrong-Way.png
If you have a few similar GET routes, there’s a danger of one overriding another.
Example 1: Two GET Routes
routes/web.php:
Route::get('posts/{post}', [PostController::class, 'show']);
Route::get('posts/create', [PostController::class, 'create']);
The problem with this pair is that “create” will match the same way as {post}
, so if you load /posts/create
in the browser, it will execute the first route of /posts/{post}
, assigning {post} == "create"
.
In that case, you need to change the order:
routes/web.php:
Route::get('posts/create', [PostController::class, 'create']);
Route::get('posts/{post}', [PostController::class, 'show']);
Then, both routes would start working.
Example 2: Resource Controller with Extra Method
routes/web.php:
Route::resource('posts', PostController::class);
Route::get('posts/export', [PostController::class, 'export']);
If you launch /posts/export
in the browser, it will instead execute the show()
method of the Controller, and not the export()
method.
The reason: as a part of Resource Controller, there’s a show()
method, which has a signature of posts/{post}
. So it will match the same way as posts/export
.
If you want to add extra methods to Resource Controller, you need to add them before the Route::resource()
:
routes/web.php:
Route::get('posts/export', [PostController::class, 'export']);
Route::resource('posts', PostController::class);
The general rule of thumb is to have specific no-parameter routes earlier in the Routes file than the “wildcard” routes with parameters.
Laravel News Links