Lumen——通过中间件修改路由

Lumen - modifying the route through middleware

所以我有一个 api 版本的中间件,我在 laravel 5 中使用它,我想在 lumen 中使用它。然而,它在中间件中使用了 getAction()setAction(),这对 lumen ("yet") 是不可用的。如果我这样做 $request->route()[1] 我可以获得当前路线但是用新路线更新它没有好处。我考虑过克隆请求并修改它,但我不知道我需要请求对象的哪一部分 "update".

这是我的路线:

$app->group(['middleware' => ['api-version']], function() use ($app) {
    $app->get('users', '{api-namespace}\UsersController@index');
    $app->get('vips/{per_page?}', '{api-namespace}\VipsController@index');
    $app->get('vip/{id}/profile', '{api-namespace}\VipsController@showProfile');
    $app->get('vip/{id}', '{api-namespace}\VipsController@show');
});

谁能告诉我如何使用我的简单路由更新来更新请求?

我在寻找解决方案时发现了这个。这是我在 Lumen 5.4 中使用中间件时想到的。

首先,我创建了一个 ExtractApiVersionMiddleware,它从 Accept header 中提取版本。我使用了 accept header 因为并非所有传递的 header 都是可信的并且它正在成为 "Best Practice":以这种方式传递 API 版本:

<?php

namespace App\Http\Middleware;

use Closure;

class ExtractApiVersionMiddleware
{
/**
 * Handle an incoming request.
 *
 * @param  \Illuminate\Http\Request $request
 * @param  \Closure $next
 *
 * @return mixed
 */
public function handle($request, Closure $next)
{
    $app = app();
    $version = "0";
    foreach (explode(';', $request->header('accept')) as $frag) {
        if (stristr($frag, "version=")) {
            $version = str_replace("version=", "", $frag);
            break;
        }
    }

    if ($version != 0) {
        $app->group(['namespace' => "App\Http\Controllers\V{$version}\Reductions"],
            function () use ($app, $version) {
            require base_path() . "/routes/web/v{$version}.php";
        });
    } else {
        $app->group(['namespace' => 'App\Http\Controllers\V0'], function () use ($app, $version) {
            require base_path() . "/routes/web/v0.php";
        });
    }

    return $next($request);
}
}

其次,我根据版本为我的代码命名空间(遗留代码库尚未消亡)。

第三,我在 Accept 中传递调用使用的版本 header Accept: application/json;version=1

第四,我为每个支持的版本准备了单独的路由文件。因此,我没有为我的所有路线设置 web.php,而是在路线下创建了一个 web 文件夹,并将我的版本文件放在那里 v0.php & v1.php

因此,当我发出请求时,中间件会提取 API 版本并根据版本号启用适当的路由组。这使版本保持干净和独立,但仍然使我能够使用我的模型获得 'creative'。

希望这对您有所帮助。我不得不应用这个解决方案,因为我不确定在 pre-release 形式

中使用 Dingo API