我正在使用Laravel作为具有许多端点和许多控制器的API。我正在使用Route::resource()
方法来定义REST端点,但是在大多数情况下,我需要再添加一个端点,现在我的代码看起来像这样:
Route::get('product/list', 'ProductController@all');
Route::resource('product', 'ProductController');
Route::get('property/list', 'PropertyController@all');
Route::resource('property', 'PropertyController');
Route::get('customer/list', 'CustomerController@all');
Route::resource('customer', 'CustomerController');
...此示例不断出现。我认为需要一种实用且更好的方法来在一处定义此{resource}/list
URI。现在,我需要重复此示例:
Route::get('{resource}/list', 'NameOfController@all');
是否有更好的解决方案来仅定义一次此端点并在每个控制器中可用?我可以避免重复吗?
答案 0 :(得分:1)
如果您查看resource
类中的Illuminate\Routing\Router
方法,将会看到以下内容:
if ($this->container && $this->container->bound(ResourceRegistrar::class)) {
$registrar = $this->container->make(ResourceRegistrar::class);
} else {
$registrar = new ResourceRegistrar($this);
}
这意味着您可以绑定ResourceRegistrar
来覆盖Laravel提供的默认值。因此,要实现所需的功能,您可以首先创建一个新类,例如app/ResourceRegistrar.php
,该类将扩展Illuminate\Routing\ResourceRegistrar
并添加默认的'list'
:
<?php
namespace App;
use Illuminate\Routing\ResourceRegistrar as BaseResourceRegistrar;
class ResourceRegistrar extends BaseResourceRegistrar
{
protected $resourceDefaults = [
'index', 'create', 'store', 'show', 'edit', 'update', 'destroy', 'list',
];
/**
* Add the list method for a resourceful route.
*
* @param string $name
* @param string $base
* @param string $controller
* @param array $options
* @return \Illuminate\Routing\Route
*/
public function addResourceList($name, $base, $controller, $options)
{
$uri = $this->getResourceUri($name).'/all';
$action = $this->getResourceAction($name, $controller, 'list', $options);
return $this->router->get($uri, $action);
}
}
然后,您只需在AppServiceProvider
中绑定注册服务商:
<?php
namespace App\Providers;
use App\ResourceRegistrar;
use Illuminate\Routing\Router;
use Illuminate\Routing\ResourceRegistrar as BaseResourceRegistrar;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
app()->bind(BaseResourceRegistrar::class, function () {
return new ResourceRegistrar(app()->make(Router::class));
});
}
}
您可以像以前一样注册路线,而无需添加多余的行:
Route::resource('product', 'ProductController');
Route::resource('property', 'PropertyController');
Route::resource('customer', 'CustomerController');
然后,如果您运行php artisan route:list
,则应该看到{resource}/list
路线。
答案 1 :(得分:1)
我做到了。您需要扩展注册商
# I made mine in app/Overrides/Router.php
<?php
namespace App\Overrides;
use Illuminate\Routing\Router as BaseRouter;
class Router extends BaseRouter
{
// You can call it however you want. These are the params you need to pass the original resource() method.
public function listResource($name, $controller, array $options = [])
{
// What make a get route and then a normal resource route you'll be able to call optional methods on.
$this->get($name.'/all', $controller.'@all')->name($name.'.all');
return $this->resource($name, $controller, $options);
}
}
$app->singleton('router', function ($app) {
return new \App\Overrides\Router($app['events'], $app);
});
现在为示例:
Route::listResource('users', 'UserController');
> php artisan r:l
+--------+-----------+----------------------+---------------+---------------------------------------------+--------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+-----------+----------------------+---------------+---------------------------------------------+--------------+
| | GET|HEAD | users | users.index | App\Http\Controllers\UserController@index | web |
| | POST | users | users.store | App\Http\Controllers\UserController@store | web |
| | GET|HEAD | users/create | users.create | App\Http\Controllers\UserController@create | web |
| | GET|HEAD | users/list | users.list | App\Http\Controllers\UserController@all | web |
| | GET|HEAD | users/{user} | users.show | App\Http\Controllers\UserController@show | web |
| | PUT|PATCH | users/{user} | users.update | App\Http\Controllers\UserController@update | web |
| | DELETE | users/{user} | users.destroy | App\Http\Controllers\UserController@destroy | web |
| | GET|HEAD | users/{user}/edit | users.edit | App\Http\Controllers\UserController@edit | web |
+--------+-----------+----------------------+---------------+---------------------------------------------+--------------+