拦截 Laravel 路由
Intercept Laravel Routing
我正忙于在 Laravel 5.1 中构建 Restful API,其中 API 版本通过 header 传递。这样我就可以对功能进行版本控制,而不是复制和粘贴整个路由组并增加版本号。
我遇到的问题是我想要版本控制方法,IE:
public function store_v1 (){ }
我在我的路线上添加了一个中间件,我从 header 捕获版本,但现在需要修改请求以从控制器选择正确的方法。
app/Http/routes.php
Route::group(['middleware' => ['apiversion']], function()
{
Route::post('demo', 'DemoController@store');
}
app/Http/Middleware/ApiVersionMiddleware.php
public function handle($request, Closure $next)
{
$action = app()->router->getCurrentRoute()->getActionName();
// dd($action)
// returns "App\Http\Controllers\DemoController@store"
}
从这里开始,我会将 header 版本附加到 $action,然后通过 $request 传递它,以便它到达正确的方法。
好吧,不管怎样,这就是理论。
关于如何将动作注入路由有什么想法吗?
我认为中间件可能不是最好的选择。您有权访问路由,但它不提供修改将调用的控制器方法的途径。
更简单的选择是注册一个自定义路由调度程序,它根据请求和路由处理调用控制器方法的逻辑。它可能看起来像这样:
<?php
class VersionedRouteDispatcher extends Illuminate\Routing\ControllerDispatcher {
public function dispatch(Route $route, Request $request, $controller, $method)
{
$version = $request->headers->get('version', 'v1'); // take version from the header
$method = sprintf('%s_%s', $method, $version); // create target method name
return parent::dispatch($route, $request, $controller, $method); // run parent logic with altered method name
}
}
拥有此自定义调度程序后,将其注册到您的 AppServiceProvider 中:
public function register() {
$this->app->singleton('illuminate.route.dispatcher', VersionedRouteDispatcher::class);
}
这样您将用您自己的路由调度程序覆盖默认路由调度程序,该路由调度程序将在控制器方法名称后缀取自请求 header.
一种粗略的替代方法是在 public 文件夹中创建指向 public 文件夹的符号链接。使用中间件读取 url 并设置可在控制器中使用的全局配置以确定要显示的内容。不理想,但它有效。
我正忙于在 Laravel 5.1 中构建 Restful API,其中 API 版本通过 header 传递。这样我就可以对功能进行版本控制,而不是复制和粘贴整个路由组并增加版本号。
我遇到的问题是我想要版本控制方法,IE:
public function store_v1 (){ }
我在我的路线上添加了一个中间件,我从 header 捕获版本,但现在需要修改请求以从控制器选择正确的方法。
app/Http/routes.php
Route::group(['middleware' => ['apiversion']], function()
{
Route::post('demo', 'DemoController@store');
}
app/Http/Middleware/ApiVersionMiddleware.php
public function handle($request, Closure $next)
{
$action = app()->router->getCurrentRoute()->getActionName();
// dd($action)
// returns "App\Http\Controllers\DemoController@store"
}
从这里开始,我会将 header 版本附加到 $action,然后通过 $request 传递它,以便它到达正确的方法。
好吧,不管怎样,这就是理论。
关于如何将动作注入路由有什么想法吗?
我认为中间件可能不是最好的选择。您有权访问路由,但它不提供修改将调用的控制器方法的途径。
更简单的选择是注册一个自定义路由调度程序,它根据请求和路由处理调用控制器方法的逻辑。它可能看起来像这样:
<?php
class VersionedRouteDispatcher extends Illuminate\Routing\ControllerDispatcher {
public function dispatch(Route $route, Request $request, $controller, $method)
{
$version = $request->headers->get('version', 'v1'); // take version from the header
$method = sprintf('%s_%s', $method, $version); // create target method name
return parent::dispatch($route, $request, $controller, $method); // run parent logic with altered method name
}
}
拥有此自定义调度程序后,将其注册到您的 AppServiceProvider 中:
public function register() {
$this->app->singleton('illuminate.route.dispatcher', VersionedRouteDispatcher::class);
}
这样您将用您自己的路由调度程序覆盖默认路由调度程序,该路由调度程序将在控制器方法名称后缀取自请求 header.
一种粗略的替代方法是在 public 文件夹中创建指向 public 文件夹的符号链接。使用中间件读取 url 并设置可在控制器中使用的全局配置以确定要显示的内容。不理想,但它有效。