【问题标题】:Route path for different api version in zend framework 3zend框架3中不同api版本的路由路径
【发布时间】:2017-11-08 12:46:43
【问题描述】:

这就是我为我的 api 定义路由的方式。它以 /api/v1 为前缀。但是现在 api v2 中添加了一些新模块,并且所有 v1 api 都保持不变并且在 v2 中可用。我如何修改这些路由,以服务于属于 /api/v1 的所有路由,并且当 /api/v1 被调用时,它应该在 /api/v2 被调用时同时服务于 /api/v2 和 /api/v1?

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,
        ),
    ),
),

【问题讨论】:

    标签: php zend-framework3 zend-route


    【解决方案1】:

    您可以将那些常见的 v1v2 移动到单个父路由,并将 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
        ]
    ];
    

    如果你不想使用子路由,你可以简单地添加一个路由参数/约束而不是/v1

    return [
        'product' => [
            'options' => [
                'constraints' => [
                    'id'      => '…',
                    'version' => 'v1|v2'
                ],
                'defaults' => ['controller' => CategoryController::class],
                'route' => '/api/:version/categories[/:id]'
            ],
            'type' => Segment::class
        ]
    ];
    

    【讨论】:

      【解决方案2】:

      我知道这已经晚了,但我刚刚发现了这个问题。

      虽然@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. **/
                  ],
              ],
      

      这允许您使用控制器的不同“版本”,并且更短、更易于理解且符合标准。

      享受吧!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-04-20
        • 2012-06-05
        • 2012-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多