?
? ????? PHP ??? ???? ??? ?? ??
你的API應(yīng)該是版本化的。不像你完全控制在客戶(hù)端和服務(wù)器端Web應(yīng)用程序代碼, 對(duì)于A(yíng)PI,您通常沒(méi)有對(duì)API的客戶(hù)端代碼的控制權(quán)。 因此,應(yīng)該盡可能的保持向后兼容性(BC),如果一些不能向后兼容的變化必須引入 APIs,你應(yīng)該增加版本號(hào)。你可以參考Semantic Versioning?有關(guān)設(shè)計(jì)的API的版本號(hào)的詳細(xì)信息。
關(guān)于如何實(shí)現(xiàn)API版本,一個(gè)常見(jiàn)的做法是在A(yíng)PI的URL中嵌入版本號(hào)。 例如,http://example.com/v1/users
代表/users
版本1的API. 另一種API版本化的方法最近用的非常多的是把版本號(hào)放入HTTP請(qǐng)求頭,通常是通過(guò)Accept
頭, 如下:
// 通過(guò)參數(shù)Accept: application/json; version=v1
// 通過(guò)vendor的內(nèi)容類(lèi)型Accept: application/vnd.company.myapp-v1+json
這兩種方法都有優(yōu)點(diǎn)和缺點(diǎn), 而且關(guān)于他們也有很多爭(zhēng)論。 下面我們描述在一種API版本混合了這兩種方法的一個(gè)實(shí)用的策略:
v1
,?v2
)。 自然,API的url將包含主要的版本號(hào)。Accept
?HTTP 請(qǐng)求頭 確定小版本號(hào)編寫(xiě)條件代碼來(lái)響應(yīng)相應(yīng)的次要版本.為每個(gè)模塊提供一個(gè)主要版本, 它應(yīng)該包括資源類(lèi)和控制器類(lèi) 為特定服務(wù)版本。 更好的分離代碼, 你可以保存一組通用的 基礎(chǔ)資源和控制器類(lèi), 并用在每個(gè)子類(lèi)版本模塊。 在子類(lèi)中, 實(shí)現(xiàn)具體的代碼例如?Model::fields()
。
你的代碼可以類(lèi)似于如下的方法組織起來(lái):
api/
common/
controllers/
UserController.php
PostController.php
models/
User.php
Post.php
modules/
v1/
controllers/
UserController.php
PostController.php
models/
User.php
Post.php
v2/
controllers/
UserController.php
PostController.php
models/
User.php
Post.php
你的應(yīng)用程序配置應(yīng)該這樣:
return [
'modules' => [
'v1' => [
'basePath' => '@app/modules/v1',
],
'v2' => [
'basePath' => '@app/modules/v2',
],
],
'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']],
],
],
],
];
因此,http://example.com/v1/users
將返回版本1的用戶(hù)列表,而?http://example.com/v2/users
將返回版本2的用戶(hù)。
使用模塊, 將不同版本的代碼隔離。 通過(guò)共用基類(lèi)和其他類(lèi) 跨模塊重用代碼也是有可能的。
為了處理次要版本號(hào), 可以利用內(nèi)容協(xié)商 功能通過(guò) yii\filters\ContentNegotiator 提供的行為。contentNegotiator
?行為可設(shè)置 yii\web\Response::acceptParams 屬性當(dāng)它確定 支持哪些內(nèi)容類(lèi)型時(shí)。
例如, 如果一個(gè)請(qǐng)求通過(guò)?Accept: application/json; version=v1
被發(fā)送, 內(nèi)容交涉后,yii\web\Response::acceptParams將包含值['version' => 'v1']
.
基于?acceptParams
?的版本信息,你可以寫(xiě)條件代碼 如 actions,resource classes,serializers等等。