zend framework 3 中不同 api 版本的路由路径
Route path for different api version in zend framework 3
这就是我为 api 定义路线的方式。它以 /api/v1 为前缀。但是现在 api v2 中添加的新模块很少,所有 v1 api 都保持不变并且在 v2 中可用。我如何修改这条路线,使其服务于属于 /api/v1 的所有路线,当调用 /api/v1 时,它应该同时服务于 /api/v2 和 /api/v1 当 /api/v2 是叫什么?
module.config.php
'product' => array(
'type' => 'Zend\Router\Http\Segment',
'options' => array(
'route' => '/api/v1/categories[/:id]',
'defaults' => array(
'controller' => CategoryController::class,
),
),
),
'products' => array(
'type' => 'Zend\Router\Http\Segment',
'options' => array(
'route' => '/api/v1/products[/:id]',
'defaults' => array(
'controller' => ProductsController::class,
),
),
),
// ... at lots of v1 apis
//these are introduced in v2
'trends' => array(
'type' => 'Zend\Router\Http\Segment',
'options' => array(
'route' => '/api/v2/trends[/:id]',
'defaults' => array(
'controller' => TrendsController::class,
),
),
),
您可以将那些常见的 v1
和 v2
移动到单个父路由,并将 v2
-only 移动到另一个父路由。下面是示例(未测试)代码,可以帮助您理解这个想法。
return [
// in Config.router.routes
'api' => [
'child_routes' => [
'v1' => [
'child_routes' => [
// your API 1-and-2 routes
'product' => [/* … */],
'products' => [/* … */]
],
'may_terminate' => false,
'options' => [
'constraints' => ['version' => 'v1|v2'],
'route' => '/:version'
],
'type' => Segment::class
],
'v2' => [
'child_routes' => [
// your API 2 routes
'trends' => [/* … */]
],
'may_terminate' => false,
'options' => ['route' => '/v2'],
'type' => Literal::class
]
],
'may_terminate' => false,
'options' => ['route' => '/api'],
'type' => Literal::class
]
];
如果您不想使用子路由,您可以简单地添加路由 parameter/constraint 而不是 /v1
:
return [
'product' => [
'options' => [
'constraints' => [
'id' => '…',
'version' => 'v1|v2'
],
'defaults' => ['controller' => CategoryController::class],
'route' => '/api/:version/categories[/:id]'
],
'type' => Segment::class
]
];
我知道这已经晚了,但我刚刚发现了这个问题。
虽然@gsc 的回答还可以,但这不是正确的答案。
这是正确答案,我是这样使用的:
'api' => [
/** Our main route is /api **/
'may_terminate' => true,
'options' => ['route' => '/api'],
'type' => Literal::class,
'child_routes' => [
/** Since our main route is /api, this will become /api/v1/YOUR_ACTIONS **/
'v1' => [
'type' => Segment::class,
'options' => [
'route' => '/v1[/:action]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
],
'defaults' => [
'controller' => Controller\ApiV1Controller::class,
'action' => 'index',
],
],
],
/** Since our main route is /api, this will become /api/v2/YOUR_ACTIONS **/
'v2' => [
'type' => Segment::class,
'options' => [
'route' => '/v2[/:action]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
],
'defaults' => [
'controller' => Controller\ApiV2Controller::class,
'action' => 'index',
],
],
],
/** Add as many "versions" as you want, all with different controllers. **/
],
],
这允许您使用不同的 "versions" 控制器,并且更短、更易理解并且符合标准。
尽情享受吧!
这就是我为 api 定义路线的方式。它以 /api/v1 为前缀。但是现在 api v2 中添加的新模块很少,所有 v1 api 都保持不变并且在 v2 中可用。我如何修改这条路线,使其服务于属于 /api/v1 的所有路线,当调用 /api/v1 时,它应该同时服务于 /api/v2 和 /api/v1 当 /api/v2 是叫什么?
module.config.php
'product' => array(
'type' => 'Zend\Router\Http\Segment',
'options' => array(
'route' => '/api/v1/categories[/:id]',
'defaults' => array(
'controller' => CategoryController::class,
),
),
),
'products' => array(
'type' => 'Zend\Router\Http\Segment',
'options' => array(
'route' => '/api/v1/products[/:id]',
'defaults' => array(
'controller' => ProductsController::class,
),
),
),
// ... at lots of v1 apis
//these are introduced in v2
'trends' => array(
'type' => 'Zend\Router\Http\Segment',
'options' => array(
'route' => '/api/v2/trends[/:id]',
'defaults' => array(
'controller' => TrendsController::class,
),
),
),
您可以将那些常见的 v1
和 v2
移动到单个父路由,并将 v2
-only 移动到另一个父路由。下面是示例(未测试)代码,可以帮助您理解这个想法。
return [
// in Config.router.routes
'api' => [
'child_routes' => [
'v1' => [
'child_routes' => [
// your API 1-and-2 routes
'product' => [/* … */],
'products' => [/* … */]
],
'may_terminate' => false,
'options' => [
'constraints' => ['version' => 'v1|v2'],
'route' => '/:version'
],
'type' => Segment::class
],
'v2' => [
'child_routes' => [
// your API 2 routes
'trends' => [/* … */]
],
'may_terminate' => false,
'options' => ['route' => '/v2'],
'type' => Literal::class
]
],
'may_terminate' => false,
'options' => ['route' => '/api'],
'type' => Literal::class
]
];
如果您不想使用子路由,您可以简单地添加路由 parameter/constraint 而不是 /v1
:
return [
'product' => [
'options' => [
'constraints' => [
'id' => '…',
'version' => 'v1|v2'
],
'defaults' => ['controller' => CategoryController::class],
'route' => '/api/:version/categories[/:id]'
],
'type' => Segment::class
]
];
我知道这已经晚了,但我刚刚发现了这个问题。
虽然@gsc 的回答还可以,但这不是正确的答案。
这是正确答案,我是这样使用的:
'api' => [
/** Our main route is /api **/
'may_terminate' => true,
'options' => ['route' => '/api'],
'type' => Literal::class,
'child_routes' => [
/** Since our main route is /api, this will become /api/v1/YOUR_ACTIONS **/
'v1' => [
'type' => Segment::class,
'options' => [
'route' => '/v1[/:action]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
],
'defaults' => [
'controller' => Controller\ApiV1Controller::class,
'action' => 'index',
],
],
],
/** Since our main route is /api, this will become /api/v2/YOUR_ACTIONS **/
'v2' => [
'type' => Segment::class,
'options' => [
'route' => '/v2[/:action]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
],
'defaults' => [
'controller' => Controller\ApiV2Controller::class,
'action' => 'index',
],
],
],
/** Add as many "versions" as you want, all with different controllers. **/
],
],
这允许您使用不同的 "versions" 控制器,并且更短、更易理解并且符合标准。
尽情享受吧!