APIとソフトウェアに見るバージョン管理の相違

今回はAPIのバージョン管理について主なパターンと、既存のソフトウェアで使われるバージョン管理との相違点について紹介します。

パス

もっともオーソドックスな方法と言えます。多くの場合、次のようになります。

/v1/users

またはバージョン番号を日付で行っているケースもあります。

/2016-06-01/users

バージョン番号を持たせるケースの場合、何をもってv2にするかが問題になります。日付の場合、リリースしたタイミング(その日付)を使うので数字の付け方に悩むことはないでしょう。

ただし、これらの方法の場合、何をもってバージョンを上げるか という問題が常に付きまといます。既存の修正なのか、バージョンアップなのかの区別が判断しづらいということです。できればリリース前にバージョンの付け方をルール化しておくのがいいでしょう。

また、v2を作った場合にすべてのAPIがインタフェースを変える訳ではないという問題があります。usersは変えたとしても、productsやその他のインタフェースはそのままで良いというケースがほとんどでしょう。そうした時に、あるAPIは常に古い日付であったり、逆に更新されていないけれどもバージョンが上がってしまうAPIが出ることになります。

HTTPヘッダー

バージョンをHTTPヘッダーに含めるケースがあります。このメリットとしては、パスのようにアクセス先を変えないで済むということです。エンドポイントはAPIのバージョンが上がったとしても変わりません。利用者としては常に同じURLで使えるというのはメリットがあります。

デメリットとしては多くの場合、HTTPアクセス部分は共通化して作られるため、usersはv2、productsはv1といった具合に切り替えるのは簡単ではないということです。特にHTTPヘッダーのような情報は共通化した上で、v1またはv2という文字列で固定されてしまっている可能性があります。

SDKやライブラリです隠蔽する方法も考えられますが、それでもバージョンを指定してもらうというのは余計な手間を増やしてしまうためあまり良いと方法とは言えないでしょう。

クエリー

クエリー文字列の中でバージョンを指定する方法もあります。こちらはHTTPヘッダーと同じでエンドポイントは常に同じです。そしてURIのクエリーの中でバージョンを指定します。HTTPヘッダーよりは変えやすい印象です。

この場合、バージョンを固定しておけば返ってくる情報は常に同じという安心感があります。パスで指定するケースに比べて、管理単位が細くなる印象です。

// パスでの指定
/v1/users
/v1/products
/v2/users    // v1とは別なレスポンス
/v2/products   // v1と同じレスポンス

// クエリーでの指定
/users?v=1
/users?v=2
/products?v=1

クエリーでの指定の場合、v=2は存在しないことになります。開発者としては新しいデータ取得法を使いたい場合はv=2を指定し、そうでない場合はv=1を指定することになります。

デメリットとしては共通したアクセスになるので、クエリーでの指定を見てレスポンスを返す分、ソースコードの分岐が増えてしまいます。徐々にソースコードが汚くなるかも知れません。

case params[:v]
when '1'
  // バージョン1を指定した場合
when '2'
  // バージョン2を指定した場合
end

もちろん最初からバージョンアップする前提で作られている場合は綺麗に設計もできるのですが、多くの場合バージョン番号は用意していても使うための仕組みはないケースが殆どです。

一般的バージョン管理との相違

パスにバージョン情報を入れた場合、印象としてはSubversionのような全体でバージョン番号を持ったバージョン管理に近い印象になります。もちろん、更新されていない /v2/productsに対してアクセスがあったら/v1/productsを呼び出すといった形にできますが、利用者としては v1 と v2 で何が違うのかと疑問に思ってしまうことでしょう。ドキュメントにその説明を載せるのも面倒です。

かつてあったCVSの場合、バージョン管理はファイル単位になります。クエリを使った方法はこれに近いものになるでしょう。アクセス先単位でバージョン番号を指定するのはあまり筋が良いとは思いませんが、現実的かも知れません。この場合、アクセス先単位でドキュメントに v1、v2の相違について掲載できるようになります。

Gitのような分散型バージョン管理の考え方をAPIのバージョン管理に適用した場合はどうなるでしょうか。これは2つの考え方ができます。

タグを使った全体の制御

まず大きなリリース単位によってタグを使います。このタグはパスに含めるのが良いでしょう。v1、v2相当になります。

アクセス先単位での細かい指定

さらに細かく動作を指定したい場合はクエリ文字列を使って設定できるようにします。これは次のタグに至るまでの細かいバージョン番号と言えます。基本的にはタグを使ったものだけで十分でしょう。


APIのバージョン管理はあまりうまくいっていないケースが多い印象があります。どのタイミングでバージョンを上げるか、後方互換性をどう維持するか、修正と機能追加の違いは何かといった具合です。

これらは既存のソフトウェアのバージョン管理が参考になると言えます。メジャー、マイナーアップデートなどの考え方、APIの開発計画に合わせてバージョン更新を考えていくのが良いでしょう。多くの場合、一度目のバージョンアップを躊躇してしまうためにずっと同じバージョン番号で更新を重ねてしまうようです。最初のバージョンアップは事前の計画に沿って進めていくのが良いでしょう。

© NTT Communications Corporation 2014