DRFフレームAPIバージョン管理の実現方法解析


APIは一定のものではない。既存のAPIの追加または削除は、そのクライアントの呼び出しに影響を与える。APIの削除が管理されていない場合、APIの増加と減少に伴い、そのクライアントを呼び出して、徐々に困惑に陥ることがありますが、どのAPIが利用可能ですか?どうして前に利用できたAPIがまた使えなくなりましたか?どのAPIが追加されましたか?APIの管理を便利にするために、バージョン機能を導入します。
APIにバージョン番号を付けて、ある特定のバージョンでは、既存のAPIは常に利用可能である。APIに重大な変更がある場合は、新しいバージョンのAPIをリリースし、ユーザーAPIが変更されたことをタイムリーに通知し、ユーザーに新しいAPIへの移行を促すことで、クライアントにバッファ移行期間を提供することができます。昨日のようなAPIは、今日は突然エラーを報告しました。
django-ress-frame eworkは、複数のAPIバージョンの補助クラスを提供し、それぞれ異なるAPIバージョンの管理方式を実現する。実用的なものは:
Accept Header Verssioning
このクラスは、クライアントがHTTPのAcceptリクエストヘッダにバージョン番号を付けて、要求したいAPIバージョンを示すことを要求しています。例えば、以下のような要求があります。
GET/bookings/HTTP/1.1
Host:example.com
Accept:appication/json;version=1.0
これは要求バージョン番号が1.0のインターフェースです。
URLPath Verssioning
このクラスの要求は、クライアントが要求するurlにバージョン番号を指定しています。一つの欠点は、URLモードを書く時に、キーワードがversionのモードである必要があります。例えば、公式サイトの一例です。

urlpatterns = [
  url(
    r'^(?P<version>(v1|v2))/bookings/$',
    bookings_list,
    name='bookings-list'
  ),
  url(
    r'^(?P<version>(v1|v2))/bookings/(?P<pk>[0-9]+)/$',
    bookings_detail,
    name='bookings-detail'
  )
]
これは不便ですので、私たちは普段使いません。
Namespace Verssioning
上記のURLPath Verssioningと似ていますが、バージョン番号はURLモードではなく、namespaceパラメータで指定されています。
もちろん、django-ress-frame ewarkは他にもHostName Versiong、QueryParameterVerssioningなどのバージョン管理補助類を提供しています。文書を自分で確認することができます。https://www.django-rest-framework.org/api-guide/versioning/
総合的に見ると、Namespace VerssioningモードはURLの設計と管理に便利であり、このようなAPIバージョンの管理方式を採用することになっています。
appiバージョン管理を開くために、プロジェクトの構成に下記の構成を追加します。

settings/common.py
REST_FRAMEWORK = {
  'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.NamespaceVersioning',
  'DEFAULT_VERSION': 'v1'
}
以上の2つの設定は、それぞれグローバル指定で使用されるAPIバージョン管理方式とクライアントデフォルトバージョン番号の場合、デフォルト要求のAPIバージョンである。これらの構成項目は単一のビューまたは図セットの範囲で指定することもできますが、統一されたバージョン管理モードがより望ましいので、グローバル構成で指定します。
次に、登録されたAPIインターフェースの前にバージョン番号を付ける。

blogproject/urls.py
urlpatterns = [
  # ...
  path("api/v1/", include((router.urls, "api"), namespace="v1")),
]
ここでは、以前よりも多くなったnamespaceパラメータは、パラメータ値v 1であり、含まれるURLモードがv 1という名前空間に属することを表す。もう一つの注意が必要です。include関数に対して、namespaceの値を指定すると、最初のパラメータは元のグループでなければなりません。patterns,ap_私達はここでap_を作ります。nameはapiに指定されています。
バージョン管理を開始すると、すべての要求対象者requestが一つの属性versionを追加します。その値はユーザ要求のバージョン番号です。VERIONの値)。したがって、要求において異なるバージョンの要求に対して異なるコード論理を実行することができる。例えば、私達のブログは記事リストAPIを修正して、データを返すフィールドをいくつか変えて、バージョンv 2で発表しています。ユーザーの要求のバージョンによって、異なるデータを返してもいいです。すなわち、APIが追加されて、元のアプリに対する互換性を維持します。

if request.version == 'v1':
	return PostSerializerV1()
return PostSerializer
if分岐は一時コードとして認識され、適切な方法でユーザーに警告できます。APIはすでに変更されています。早く新しいバージョンv 2に移行してください。そして、未来のある時間に、大部分のユーザが新版アプリに移行したことを確認して、これらのコードを除去し、標準バージョンをv 2に設定します。このように、元々のv 1バージョンのAPIは完全に廃棄されます。
もちろん、現在のブログインターフェースはまだアップグレードのところを修正する必要がありませんが、APIバージョン管理の設定が有効になったかどうかをテストするために、テスト用のビデオセットを追加すると思います。中で異なるバージョンに対する要求を処理します。
まずブログ/views.pyに簡単なテスト用の画像集を入れます。このビューにはテスト用のインターフェースがあります。インターフェースの処理ロジックはバージョン番号によって違います。

class ApiVersionTestViewSet(viewsets.ViewSet):
  @action(
    methods=["GET"], detail=False, url_path="test", url_name="test",
  )
  def test(self, request, *args, **kwargs):
    if request.version == "v1":
      return Response(
        data={
          "version": request.version,
          "warning": "     v1      ,       v2   ",
        }
      )
    return Response(data={"version": request.version})
もちろんビューセットはrouterに登録することを忘れないでください。
blogproject/urls.py

blogproject/urls.py

#     API       
router.register(
  r"api-version", blog.views.ApiVersionTestViewSet, basename="api-version"
)
これはインターフェースのバージョンアップに相当します。v 2名前空間のインターフェースに追加します。

urlpatterns = [
  path("api/v1/", include((router.urls, "api"), namespace="v1")),
  path("api/v2/", include((router.urls, "api"), namespace="v2")),
]
含まれているURLは同じですが、namespaceはv 2です。
効果をテストしてみます。開発サーバを起動して、まずバージョン番号v 1のテストインターフェースにアクセスしてください。結果は下記の通りです。

GET /api/v1/api-version/test/
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
  "version": "v1",
  "warning": "     v1      ,       v2   "
}
またバージョン番号v 2のテストインターフェースにアクセスして、返ってきた内容はv 2です。

GET /api/v2/api-version/test/

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
  "version": "v2"
}
他のインターフェースについては、v 1にかかわらず、v 2バージョンのインターフェースがアクセスでき、これは、互換性のあるインターフェースアップグレードが完了したことに相当する。
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。