-
-
Notifications
You must be signed in to change notification settings - Fork 70
Description
Describe the bug
When you setup routes via resource()
or apiResource()
and add custom routes (for example a search route) like in the following example, then the search
part of the request will be interpreted as the ID in a normal GET request.
app()->resource('/users', 'UsersController');
app()->get('/users/search', 'UsersController@search);
The problem lies in the router, i.e. in resource()
and apiResource()
where the routes are created with {id}
in the paths:
static::match('DELETE', "$pattern/{id}", "$controller@destroy");
static::match('PUT|PATCH', "$pattern/{id}", "$controller@update");
...
For later route matching these {id}
get translated into (.*?)
which will simply match any route part that comes after the base path. E.g. for a request GET /users/search
the part search
will be interpreted as ID. As we are in resource territory we can assume that ids are numerical. So the parts in resource()
and apiResource()
with {id}
should be changed to only match numerical ids. Something like:
static::match('DELETE', "$pattern/(\d+)", "$controller@destroy");
static::match('PUT|PATCH', "$pattern/(\d+)", "$controller@update");
...
Note: as a need-to-know workaround a route like /users/search
can be registered before the resource. Like that it is being found first.
To Reproduce
Steps to reproduce the behavior:
-
Create routes as demonstrated above
-
Call
GET /users/search
-
Will most probably show some error about SQL
Expected behavior
Custom routes are matched no matter if they are registered before or after resource routes.
Additional context
Tested with Leaf 4.