日曜日, 3月 16, 2014

You need NOT API version 2 このエントリーを含むはてなブックマーク


バージョン番号をURLに含めるべき「でない」理由について、 自分はどのように考えているか具体的に述べたいと思う。

見過ごせない根本的な問題



基本的には、 http://rebuild.fm/35/ で述べられていること、それから、

http://blog.kazuhooku.com/2014/03/web-api.html http://yohei.hatenablog.com/entry/2014/03/12/001707 

 に同意である。  そこで述べられているように、

 ・拡張が容易である
 ・拡張時に後方互換性を破壊しない 

をしっかり守り、互換性を壊すことがないようにできるだけ変更を少なくしたうえで、 互換性を壊す必要がある場合は関数名を変更する、といったような感じで概ね解決できると思う。 

ただ、何というか、根本的なところで琴線に触れるものがあって、見過ごせないなあと感じている。 率直にいうと、そもそもAPIのv2を作りたくなるような状況に陥ることこそが問題ではないかと思っている。 

JSONのような拡張可能なシリアライズフォーマットを用い、拡張可能な形で入出力パラメータを設計する。これは、いわゆるスキーマレスとかソフトスキーマといわれるもので、項目が変わったとしてもシステムに影響ないような仕組みである。つまり、項目が変更されても影響なければバージョン管理はそもそも必要ないというわけ。

これはJSONだけでなくXMLやMessagepackでも同じことがいえる。 

メディアタイプでデータ表現を変えるという発想はReflexWorksに近いというか、そのものなんだけれども、RESTのリソースの概念では表現を変えてもデータは同じものであって、v2なんていう発想はない。 (もちろん、データが更新されたらリビジョンは上がるがAPIのバージョンに相当するものはない)

それから、私はJSONの文化大革命って呼んでいるのだが、過去にHTMLやXMLで積み上げたセマンティクスの議論が台無しになっている雰囲気があって、今回のようなAPIでバージョニングすべきかが問題になるのは当然の帰結のような気がしてしかたがない。 

今さら、ATOM PUBとかいうつもりはないけれど、それにしても、勝手気ままにAPI作りがちではないか? 

最悪なのは、getXXX,updateXXX というように単にエンティティに操作をつけただけの関数をモッサリ作ってる。 だから、/v2/getXXX なんて欲しくなるわけ。データこそJSONかもしれないが、これこそSOAP時代の発想じゃないか。 

HTTPのGETやPOSTほど変更に強いAPIはないわけだし、RESTで単純にHTTPメソッドへマッピングして、GET|POST /XXX でいいじゃん、と思う次第。

CRUDに当てはまらないAPI


一方で、単純にCRUDに当てはまらないものはどうするんだ?RESTでCRUD4つに集約できるなんて幻想だ!なんていうのもわかる。 

基本的にリソースは静的なデータであって、GET /XXXとすると、/XXXのデータがそのまま返る。 しかし、/XXXの結果を加工したくて、サービスとしてサーバサイドで動的にビジネスロジックを動作させたいこともある。 

例えば、消費税計算関数calcがあり、デフォルトは5%であるとしよう。以下のように書くことで、calc(/XXX)を実行する。つまり、/XXXで取得した原価のフィードを関数calc()で消費税5%で計算して返す。 

 GET /XXX?f=calc   

さらに、8%で計算するv2も定義してURLパラメータで表現する。4月以降はv2をつけて実行すればよい。 

 GET /XXX?f=calc+v2 あるいは、GET /XXX?f=calc&v=2 など。 

つまり、URLパラメータでバージョニングすればよいという結論である。

結論からいえること


いつのまにかURLにバージョン番号をつけるべきという結論になってしまっているが、言いたかったのはリソースはあくまで静的なものであって、リソースをCRUDする限りにおいてバージョニングは必要ないということ。

また、リソースの項目の追加変更においても必要ない。唯一、必要になるのはCRUDに当てはまらない一部の動的なサービスAPIであって、それでもURLパラメータで管理すればよく、API全体をバージョニングする必要はないということ。

だから、/v2/~というように、URLにバージョン番号をつけるべきではないと思う。

 
© 2006-2015 Virtual Technology
当サイトではGoogle Analyticsを使ってウェブサイトのトラフィック情報を収集しています。詳しくは、プライバシーポリシーを参照してください。