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

时间:2019-10-15 18:30:33

标签: laravel laravel-routing laravel-6

我正在使用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');

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

2 个答案:

答案 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)

我做到了。您需要扩展注册商

1/2创建路由器类

# 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);
    }   
}

2/2将其绑定到bootstrap / app.php

$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          |
+--------+-----------+----------------------+---------------+---------------------------------------------+--------------+