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
所以我有一个 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