一个好的 API 设计应该是“版本化”的:变更和新的功能应该在 API 新版本中实现,而不是在一个版本上持续更改。与Web应用程序不同,您可以完全控制客户端和服务器端 代码,APIs 是为了给超出控制的客户端使用。因此, 应该尽可能的保持向后兼容性,如果有一些变化不能向后兼容,你应该在新版本的 API 中采用它同时增加版本号。现有客户端可以继续使用旧版本的 API;新的或升级的客户端可以在新的 API 版本中获得新的功能。
提示: 可以参考 Semantic Versioning 来获取更多关于设计 API 版本号的信息
关于如何实现 API 版本,一个常见的做法是在 API 的 URL 中嵌入版本号。例如, https://example.com/v1/users 代表 /users 版本 1 的 API。
另一种 API 版本化的方法, 最近用的非常多的是把版本号放入 HTTP 请求头,通常是通过 Accept 头,如下:
// 通过参数 Accept: application/json; version=v1 // 通过vendor的内容类型 Accept: application/vnd.company.myapp-v1+json 这两种方法都有优点和缺点, 而且关于他们也有很多争论。 下面我们描述在一种 API 版本混合了这两种方法的一个实用的策略:
v1,v2)。 自然,API 的 url 将包含主要的版本号。Accept HTTP 请求头 确定小版本号编写条件代码来响应相应的次要版本。为每个模块提供一个主要版本, 它应该包括资源类和控制器类 为特定服务版本。 更好的分离代码, 你可以保存一组通用的 基础资源和控制器类, 并用在每个子类版本模块。 在子类中, 实现具体的代码例如 Model::fields()。
你的代码可以类似于如下的方法组织起来:
api/ common/ controllers/ UserController.php PostController.php models/ User.php Post.php modules/ v1/ controllers/ UserController.php PostController.php models/ User.php Post.php Module.php v2/ controllers/ UserController.php PostController.php models/ User.php Post.php Module.php 你的应用程序配置应该这样:
return [ 'modules' => [ 'v1' => [ 'class' => 'app\modules\v1\Module', ], 'v2' => [ 'class' => 'app\modules\v2\Module', ], ], 'components' => [ 'urlManager' => [ 'enablePrettyUrl' => true, 'enableStrictParsing' => true, 'showScriptName' => false, 'rules' => [ ['class' => 'yii\rest\UrlRule', 'controller' => ['v1/user', 'v1/post']], ['class' => 'yii\rest\UrlRule', 'controller' => ['v2/user', 'v2/post']], ], ], ], ]; 因此,https://example.com/v1/users 将返回版本 1 的用户列表, 而 https://example.com/v2/users 将返回版本 2 的用户。
使用模块, 将不同版本的代码隔离。 通过共用基类和其他类 跨模块重用代码也是有可能的。
为了处理次要版本号, 可以利用内容协商 功能通过 contentNegotiator 提供的行为。 contentNegotiator 行为可设置 yii\web\Response::$acceptParams 属性当它确定支持哪些内容类型时。
例如,如果一个请求通过 Accept: application/json; version=v1 被发送, 内容交涉后,yii\web\Response::$acceptParams 将包含值 ['version' => 'v1']。
基于 acceptParams 的版本信息,你可以写条件代码 如 actions,resource classes,serializers 等等。
由于次要版本需要保持向后兼容性,希望你的代码不会有 太多的版本检查。否则,有机会你可能需要创建一个新的主要版本。
Found a typo or you think this page needs improvement?
Edit it on github !
Signup or Login in order to comment.