如何扩展Laravel';Laravel 6中的基本路线资源?

如何扩展Laravel';Laravel 6中的基本路线资源?,laravel,laravel-routing,laravel-6,Laravel,Laravel Routing,Laravel 6,我使用Laravel作为一个API,有许多端点和控制器。我正在使用Route::resource()方法定义REST端点,但在大多数情况下,我需要再添加一个端点,现在我的代码如下所示: Route::get('product/list','ProductController@all'); 路由::资源(“产品”、“产品控制器”); 路由::get('属性/列表','PropertyController@all'); 路由::资源('property','PropertyController');

我使用Laravel作为一个API,有许多端点和控制器。我正在使用
Route::resource()
方法定义REST端点,但在大多数情况下,我需要再添加一个端点,现在我的代码如下所示:

Route::get('product/list','ProductController@all');
路由::资源(“产品”、“产品控制器”);
路由::get('属性/列表','PropertyController@all');
路由::资源('property','PropertyController');
路线::获取('客户/列表','CustomerController@all');
路由::资源(“客户”、“客户控制器”);
…这个样本不断出现,一次又一次。我认为需要有一种实用且更好的方法来在一个地方定义这个
{resource}/list
URI。现在我需要重复这个示例:

Route::get({resource}/list','NameOfController@all');


是否有更好的解决方案只定义此端点一次并在每个控制器中可用?我能以某种方式避免重复吗?

如果您查看
照明\路由\路由器
类中的
资源
方法,您将看到:

if ($this->container && $this->container->bound(ResourceRegistrar::class)) {
    $registrar = $this->container->make(ResourceRegistrar::class);
} else {
    $registrar = new ResourceRegistrar($this);
}
这意味着您可以绑定一个
ResourceRegister
,以覆盖Laravel提供的默认值。因此,为了实现您想要的,您可以首先创建一个新类,例如,
app/ResourceRegistrar.php
,它将扩展
illighted\Routing\ResourceRegistrar
,并添加一个默认的
“列表”

<?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);
    }
}
您可以像以前一样注册路线,而无需添加额外线路:

Route::resource('product', 'ProductController');
Route::resource('property', 'PropertyController');
Route::resource('customer', 'CustomerController');

然后,如果您运行
php artisan route:list
,您应该会看到
{resource}/list
路由。

如果您查看
照明\路由\路由器
类中的
资源
方法,您将看到:

if ($this->container && $this->container->bound(ResourceRegistrar::class)) {
    $registrar = $this->container->make(ResourceRegistrar::class);
} else {
    $registrar = new ResourceRegistrar($this);
}
这意味着您可以绑定一个
ResourceRegister
,以覆盖Laravel提供的默认值。因此,为了实现您想要的,您可以首先创建一个新类,例如,
app/ResourceRegistrar.php
,它将扩展
illighted\Routing\ResourceRegistrar
,并添加一个默认的
“列表”

<?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);
    }
}
您可以像以前一样注册路线,而无需添加额外线路:

Route::resource('product', 'ProductController');
Route::resource('property', 'PropertyController');
Route::resource('customer', 'CustomerController');

然后,如果您运行
php-artisan路由:list
,您应该会看到
{resource}/list
路由。你需要延长注册时间

1/2创建路由器类
#我在app/Overrides/Router.php中制作了我的

我成功了。你需要延长注册时间

1/2创建路由器类
#我在app/Overrides/Router.php中制作了我的

您可以扩展您自己的资源注册器,您可以调用该注册器以使用所需的额外资源注册资源route@lagbox:你能给我一个答案中的示例代码吗?贴出的答案涵盖了它。。。如果您发现特定资源不需要
列表
端点,请使用
except
不注册它
Route::resource('something','controller')->except('list')。。。您也不能绑定该类并获取您的注册器版本的实例并直接使用它。。。取决于您想要做什么您可以扩展您自己的资源注册器,您可以调用该注册器来注册您所需的额外资源route@lagbox:你能给我一个答案中的示例代码吗?贴出的答案涵盖了它。。。如果您发现特定资源不需要
列表
端点,请使用
except
不注册它
Route::resource('something','controller')->except('list')。。。您也不能绑定该类并获取您的注册器版本的实例并直接使用它。。。取决于您想做什么可以将其与
Route::apirource()
一起使用吗?我不知道需要什么才能让它工作。你能解释一下为什么
app()->bind(baseResourceRegistrator::class,function(){returnnewResourceRegistrator(app()->make(Router::class));}不是“`$this->app->bind(baseResourceRegistrator::class,ResourceRegistrator::class);``试图理解这里的差异。两者似乎都起作用了。第二种方式看起来handy@GayanKavirathne我已将答案更新为使用
$this->app
。它没有什么不同,使用
app()
只是指方法。我的观点是,为什么我们要用app作为参数来安装ResourceRegister。对我来说,看起来我们正在重新创建与应用程序相关的配置。我是这样建议的<代码>$this->app->bind(baseResourceRegistrator::class,ResourceRegistrator::class)我们只需将抽象和具体的类传递给bind方法,而无需实例化also,如果您可以在$resourceDefaults数组中添加一个关于值顺序的合理警告,这对任何新读者来说都是一个巨大的优势。我添加了一个delete方法massDelete。At一直被销毁方法消耗。由于默认的delete方法是like/product/{product},而我的新路由是like/product/massDelete,因此destroy将masDestroy作为参数使用。再次感谢您在这里所做的工作。是否可以将其与
Route::apirource()
一起使用?我不知道需要什么才能让它工作。你能解释一下为什么
app()->bind(baseResourceRegistrator::class,function(){returnnewResourceRegistrator(app()->make(Router::class));}不是“`$this->app->bind(baseResourceRegistrator::class,ResourceRegistrator::class);``试图理解这里的差异。两者似乎都起作用了。第二种方式看起来handy@GayanKavirathne我已将答案更新为使用
$this->app
。它没有什么不同,使用
app()
只是指方法。我的观点是,为什么我们要用app作为参数来安装ResourceRegister。对我来说,这看起来像是我们在重新创造