岩本隆史の日記帳(アーカイブ)

はてなダイアリーのサービス終了をうけて移行したものです。更新はしません。

私が RESTful API の後方互換性を気にするケース

前回の記事「RESTクライアントが知っているべきこと」に、id:nsiena さんからトラックバックをいただきました。

斜め上の応答になってしまうかもしれませんが、思ったことを書いてみます。

API変更の性格分類とサーバがとりうる対策

まず、APIがどのように変更されるか分類し、サーバが取りうる対策をまとめてみましょう。

API変更の性格 サーバがとりうる対策(概要のみ)
リソースのURIが変わる ステータスコードで「301 Moved Permanently」を返し、Locationヘッダで新規URIを返す。
リソースのメディアタイプが変わる Content-Typeヘッダで適切なメディアタイプを返す。リクエストのAcceptヘッダによっては、ステータスコードで「406 Not Acceptable」を返さなければならないかもしれない。その場合、送出可能なメディアタイプの一覧をレスポンスエンティティに含める。
サーバが処理可能なリクエストエンティティのメディアタイプが変わる 処理不可能なメディアタイプであれば、ステータスコードで「415 Unsupported Media Type」を返す。その場合、処理可能なメディアタイプの一覧をレスポンスエンティティに含める。
メディアタイプは変わらないが、入力パラメータが変わる(例:フォームの必須項目が増える) 処理不可能であれば、ステータスコードで「400 Bad Request」を返す。その場合、修正ヒントをレスポンスエンティティに含める。

上記いずれの場合でも、優秀なRESTクライアントならばサーバの応答を理解し、適切に対処できるはずです。

ただし、優秀でないクライアントのために後方互換性を担保したいという気持ちも私には理解できます。その場合、サーバは「URI に互換バージョンを表す識別子を含める」などして、URIセットを分割するほかないでしょう。

私自身は「いやしくもRESTクライアントを名乗るのであれば、この程度の変更ぐらい理解してくれよ」という立場です。

後方互換性が気になるのはプロトコル更新時ぐらい

そんな私にも、後方互換性が気になる状況が訪れる可能性はあります。プロトコル自体が更新されるケースです。

たとえば、AtomPubサーバを運営しているとします。数年後に AtomPub 2.0 がRFCになったとして、それに使いたい仕様が含まれているのであれば、使わない手はないでしょう。そのときは、以前のAtomPubしか理解できないクライアントを考慮して、AtomPubバージョンによってURIセットを分割するかもしれません。既存のAPIを拡張してもよいのですが、URIセットを分割する方が簡単ならばそうします。

というわけで、私が RESTful API後方互換性を気にするとすれば、プロトコルが変わるときぐらいだという話でした。原理主義的にすぎるかもしれませんが、そういう人がちょっとぐらい世の中にいたほうが楽しいではありませんか。

追記(2009-05-04)

それは問題ではない (RESTful API では後方互換性を気にする必要がない)、解決法は単純である (API変更の性格分類とサーバがとりうる対策)、という流れだと理解していたのですが。同じようにするかもしれない (後方互換性が気になるのはプロトコル更新時ぐらい)、というまとめかたなので。異議だったのか、別の解決法の提示だったのか、同意だったのか、(便乗気味に) REST のことを語るものだったのか、ちょっと分からなくなりました。

RESTful API の後方互換性は HTTP より上位の層の問題が大きい - Siena.の日記

分かりづらくてすみません。私がいいたいのは、つまりこういうことです。

  1. RESTクライアントが知っているべきこと」で書いた以上のことをクライアントが知っていて、そのためにサーバが後方互換性を気にしなければならないのであれば、それは密結合であり、RESTの定義に反している。*1
  2. 後方互換性が気になることがあるとすれば、それはプロトコルが更新される(通信プロトコルや初期URIが変わる、未定義のメディアタイプやリンク関係が新たに定義される)ケースである。過去のプロトコルバージョンしか知らないクライアントが存在するかもしれないからだ。

おそらく id:nsiena さんの考えていらっしゃるAPIの変更は2を含んでいると思われます。勝手に1であると解釈し、「RESTful API では後方互換性を気にする必要がない」と書いたのは軽率でした。申し訳ありませんでした。

追記(2009-05-07

「出力パラメーターが変わる(例: というタグがRoot直下に挿入されるようになる」の場合は...と思ったら後半 = URIセットを分割する。 | v1.0/foo, latest/foo とかしておくのでしょうかね > X-HOGE-API-VERSION ヘッダとかは...?

はてなブックマーク - yssk22のブックマーク

「出力パラメーターが変わる=リソースのメディアタイプが変わる」と捉えています。URIセットはそのようなイメージです。ヘッダもありだとは思いますが、結合度が少ないぶんURIセットの分割のほうが望ましいのではないかと考えています。

*1:RESTの定義に少しぐらい反していてもRESTfulなAPIは存在しえます。原理的に考えたいので無視しています。