- 既存クライアントに影響を与えずにAPIの仕様を変更したい
- 複数バージョンをどのように分けて設計・管理すればよいか分からない
- 将来的な拡張を見据えて、最初から正しいバージョニング設計をしたい
このような方は、APIのバージョン管理をするのがおすすめです。
APIのバージョン管理をする必要がある理由は、次の通り。
- 新機能を追加したいが、クライアントアプリに影響を与えたくない
- 新バージョンへの移行をスムーズにしたい
将来の互換性を維持したり新しいAPIへの移行を考慮する場合には、初期のうちからAPIバージョニング戦略を立てておくことが重要です。
本記事ではDjango REST framework(DRF)のバージョン管理方法をご紹介します。
3つのバージョン管理方法
DRFのバージョン管理方式には、大きく3つのパターンがあります。
1. URLパス方式(推奨)
URLのパスとしてバージョン情報を含める方法です。
特に理由がなければ、この方法を採用するのが間違いありません。
/api/v1/users/
URLパスにバージョン情報が含まれるので、パッと見てわかるのが一番のメリット。
urls.pyでのルーティングで制御しやすく、バックエンドの構成もわかりやすいです。
2. クエリパラメータ方式
クエリパラメータでバージョン管理する方法です。
/api/users/?version=1
SEOやキャッシュの扱いが難しいので、基本的には非推奨です。
3. ヘッダー方式(Acceptヘッダー)
クライアントからAPIへのリクエストヘッダに、以下を含める方法です。
Accept: application/json; version=1.0
APIのURLを変更せずにバージョン管理できます。
ただし、ブラウザの自動送信にバージョン情報が含めづらかったり、CORSに引っかかりやすいなど扱いの面では劣ります。
Django REST frameworkでの実装方法
ここからは推奨の「URLパス方式」を使ったバージョン管理方法をご紹介します。
最終的なディレクトリ構成は次の通りで、バージョンごとにSerializerやViewを分けて管理する形の実装です。
myapp/
└─ api/
├─ v1/
│ ├─ views.py
│ ├─ serializers.py
│ └─ urls.py
└─ v2/
├─ views.py
├─ serializers.py
└─ urls.py
順番に解説します。
settings.py
REST_FRAMEWORK = {
"DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.URLPathVersioning",
"ALLOWED_VERSIONS": ("v1", "v2"),
"DEFAULT_VERSION": "v1",
"VERSION_PARAM": "version",
}
urls.py
プロジェクト側のurls.pyには、以下のようにバージョンごとのルーティングを行います。
from django.urls import include, path
urlpatterns = [
path("api/v1/", include("myapp.api.v1.urls")),
path("api/v2/", include("myapp.api.v2.urls")),
]
これによって、パスを変更することで異なるバージョンのAPIを利用できるようになります。
api/v1/
: バージョン1を利用api/v2/
: バージョン2を利用
各Viewでのバージョン確認
念のため、以下のコードを配置して動作確認しましょう。
class SampleView(APIView):
def get(self, request):
version = request.version
return Response({"message": f"You are using API version {version}"})
リクエストすべき内容は、次のとおりです。
# api/v1/sampleにリクエスト
curl http://localhost:8000/api/v1/sample/
# レスポンス例
# {"message": "You are using API version v1"}
まとめ
DRFのAPIのバージョン管理にあたっては、URLパス方式を使うのが一般的。
設定すべき項目は、次の通りです。
- settings.py
- urls.py
また、バージョン管理にあたっては「ViewやSerializerを分離しつつ、共通処理はDRYに保つ」ことを意識すると運用が簡単です。
今後APIの仕様が増える可能性があるなら、最初から/api/v1/
構成で始めておくのが得策です。
コメント