APIのバージョニング
稼働中のAPIを更新する際に課題となるバージョニング方法の整理とMuleSoftでの推奨を紹介したいと思います。
APIエンドポイントのバージョニング
まずAPIクライアントから呼ばれるエンドポイントをバージョニングする際には一般的に以下の3つの方法が考えられます。
ディレクトリにバージョンを含むパターン
http://hogehoge-papi.cloudhub.io/api/user/v1/{userid}
ディレクトリの中でバージョン番号を明記するパターンです。
(/v1がバージョン)
APIクライアント側から見て分かりやすいというメリットがある一方、一つのサブドメイン内で全てのAPIバージョンの対応を行う必要があるため、複数バージョンを並行稼働させようとした場合には単一の実装で全て処理するか、APIバージョン毎にURL Mappingルール等で実装を振り分ける必要が出てきます。
ホスト名にAPIバージョンを含むパターン
http://hogehoge-papi-v2.cloudhub.io/api/user/{userid}
APIバージョンをサブドメインの中に含むパターンです。
(v2がバージョン)
メリットとしてはAPIバージョンがサブドメイン毎に分かれるのでAPI実装側でURLのマッピングを行う必要がないため、構成がシンプルになります。反対にAPIをバージョンアップするたびにサブドメイン名が増えていくことになるため、DNSの管理が煩雑になりがちです。
コンテントネゴシエーションでバージョン管理するパターン
http://hogehoge-papi.cloudhub.io/api/user/{userid}(HTTP Headers)
Accept-Version: V3
URIにバージョン番号を含むのではなく、HTTP Headerの中にある値でバージョンを管理するパターンです。
メリットとしてよりRESTの思想に遵守したURIを維持できるという点がありますが、視認性が低くなる点と、Webブラウザなどの任意のHeader値をセットできない環境において気軽に試すことが難しくなる点が課題となります。
MuleSoftの推奨
それぞれ一長一短があり、全てのケースにおいて万能ではないですが、MuleSoftの場合だとAPIクライアント側の利便性や視認性を重要視し、ディレクトリにバージョン番号を入れるパターンを推奨しています。
http://hogehoge-papi.cloudhub.io/api/user/v1/{userid}
このパターンで課題となるAPIバージョン毎の振り分けについては、Anypoint Platformの場合はAPI ManagerとLoad Balancerによって、実際の各バージョン毎のAPI実装をマッピングルールで紐付ける事で比較的簡単に実現出来る点も、推奨理由の一つです。
またバージョン番号自体はv2, v3, v4 という様に整数の値を用いたシンプルなバージョニングを維持する事を推奨しています。
これはAPIエンドポイントの変更はコンシューマ側に負荷をかけるため、後方互換性が維持出来ている間は同一のURIで提供されるべきとしていているためです。そのため後述のセマンティックバージョニングにおけるメジャーバージョンのみをURIに付与する様にしています。
API実装のバージョニング
APIエンドポイントに対するバージョンにはv1, v2 といった具合でバージョンを例示しましたが、実際のAPI実装にはAPIエンドポイントの構造には影響の無いバグ修正など、より細かな単位で実装が更新されていく事が想定されます。
そこでMuleSoftでは、API実装にはセマンティックバージョニングを用いることを推奨しています。
セマンティック バージョニング 2.0.0 | Semantic Versioning
https://semver.org/lang/ja/
セマンティックバージョニングとは、メジャーバージョン、マイナーバージョン、パッチバージョンを用いてソフトウェアのバージョンを管理する手法です。各バージョンの変更に明確な意味を持たせることによって、APIクライアント側が利用するAPIのバージョンを上げて良いのかどうかを判断しやすくなります。
例えばセマンティックバージョニングではバージョン1.1.5のAPIで動作していた機能はAPIバージョン1.2.5でも機能することを保証していることになるので、APIクライアントはバージョンアップが行いやすくなります。
セマンティックバージョンでは、以下の様に各バージョンに明確な意味が持たされています。
メジャーバージョン
後方互換性の無い変更が合った場合にメジャーバージョンを更新します。
これにはAPIのシェイプが変わったり、今まであったAPIが削除された等はもちろん含まれますが、APIの日付のタイムゾーンがGMTからJSTに変わったり、パラメータを省略した際のデフォルト値が変わった等、APIのシェイプに変更が無くても既存のAPIコンシューマに対して何かしらの影響を与える場合も含まれます。
マイナーバージョン
APIクライアント側の実装に変更を伴わない、後方互換性のある機能追加の場合はマイナーバージョンを増分させます。例えば新しいパラメータやディレクトリが追加された場合などがそれにあたります。また実際にはまだ削除されてはいないが特定の機能が非推奨・削除予定となった場合など、将来に渡る影響の通知などもこのマイナーバージョンを利用します。
パッチバージョン
APIのシェイプが変わらない実装側のバグ修正など、後方互換性を保ったごく小さな変更の場合にはパッチバージョンを利用します。どのような小さな修正であったとしてもリリース後の実装の修正に関してはAPIバージョンの更新が必要です。
Anypoint Platformを利用した場合のセマンティックバージョンの使い分けは以下の通りです。
メジャーバージョンのみを利用
- APIエンドポイントURL
- RAML/OASなどのAPIスペック定義 : バージョンとbaseUri
- Anypoint Exchange(APIディスカバリ)でのバージョン情報
- API Manager内の “API version”, “Implementation URL”, “Consumer endpoint”
フルセマンティックバージョンを利用
- AnyPoint Exchangeにおける”アセットバージョン”, “APIインスタンス”
- API Manager内の “Asset version”
- Maven pom.xmlファイル内のversion定義
- バージョン管理システムのブランチ・タグ
実際にAnyPoint Exchangeでは、APIをPublishする際にもこのバージョニングを強制することで、バージョニングの一貫性を担保しています。
APIのバージョニングは難しい課題ですが、APIプロバイダとAPIコンシューマが共通のルールに従うことで、バージョン変更に伴う負荷を双方で減らすことが可能となります。