2 追蹤者

版本控制

一個好的 API 應該是版本化的:變更和新功能應該在 API 的新版本中實作,而不是持續地修改同一個版本。與您可以完全控制客戶端和伺服器端程式碼的 Web 應用程式不同,API 的目的是供您無法控制的客戶端使用。因此,API 的向後相容性 (BC) 應盡可能維持。如果必須進行可能破壞 BC 的變更,您應該在 API 的新版本中引入它,並提高版本號。現有的客戶端可以繼續使用舊的、可運作的 API 版本;新的或升級的客戶端可以在新的 API 版本中獲得新功能。

提示:有關設計 API 版本號的更多資訊,請參閱 語意化版本控制

實作 API 版本控制的一種常見方法是在 API URL 中嵌入版本號。例如,https://example.com/v1/users 代表 API 版本 1 的 /users 端點。

另一種 API 版本控制方法最近越來越受歡迎,是將版本號放在 HTTP 請求標頭中。這通常透過 Accept 標頭完成

// via a parameter
Accept: application/json; version=v1
// via a vendor content type
Accept: application/vnd.company.myapp-v1+json

這兩種方法各有優缺點,並且關於每種方法都有很多爭論。下面您將看到一種實用的 API 版本控制策略,它是這兩種方法的混合

  • 將每個主要 API 版本實作放在一個單獨的模組中,其 ID 為主要版本號(例如 v1v2)。自然地,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 屬性。

例如,如果請求是使用 HTTP 標頭 Accept: application/json; version=v1 發送的,則在內容協商之後,yii\web\Response::$acceptParams 將包含值 ['version' => 'v1']

根據 acceptParams 中的版本資訊,您可以在動作、資源類別、序列化器等位置編寫條件程式碼,以提供適當的功能。

由於次要版本的定義要求維護向後相容性,因此希望您的程式碼中不會有太多版本檢查。否則,您可能需要建立一個新的主要版本。

發現錯字或您認為此頁面需要改進?
在 github 上編輯 !