Routes resolve differently when cached

But tests can help you catch the issue

Joel Clermont
Joel Clermont
2023-12-28

In yesterday's tip, I made an offhand remark about Laravel code behaving differently whether route caching is enabled or not. Maybe you were wondering if I had a specific example?

Consider the following route definitions:

Route::redirect('users', route('some-alternate-user-listing'));
Route::resource('users', UserController::class)->only(['create', 'store']);

The intention is that the first route definition would redirect a GET request for /users to some alternate route. But then we want the normal resource controller in place for creating and storing users.

There is a bug though, since redirect answers to all HTTP verbs, including POST. So we've now created an overlap in POST /users where it's defined both as a redirect and as an action on the UserController.

Which one wins? Here's where it gets tricky.

Without route caching, the last matching route definition wins. So my tests for creating a user hit my UserController as expected.

But with route caching enabled, the first matching definition wins instead! So if we ship this to production, even though tests are passing, any attempts to create a user will hit our redirect route instead.

Here to help,

Joel

P.S. Sometimes a team holds off hiring or contracting because it's a big commitment. Did you know you can bring us on for just a month at a time? Pause and resume anytime you like.

Toss a coin in the jar if you found this helpful.
Want a tip like this in your inbox every weekday? Sign up below 👇🏼

Level up your Laravel skills!

Each 2-minute email has real-world advice you can use.