REST API のバージョン管理 (リソース自体ではなく、表現のみをバージョン管理します)
-
19-09-2019 - |
質問
見てみました API のバージョン管理のベスト プラクティスは?, 、しかし、答えに完全に納得していないので、より具体的な例でバージョン管理の部分を再度質問します。2 つの URI があります (1 つは URI の一部としてバージョン管理があり、もう 1 つはバージョン管理がありません)。
http://xxxx/v1/user/123 -> favored solution in discussed thread
http://xxxx/user/123
最初のリンクが REST の概念を表現しているかどうかは疑問です。見つけました http://xxxx/v1/user/123
いつか次のようなより高い API バージョンが存在することを示唆しているため、混乱を招きます http://xxxx/v2/user/123
. 。しかし、これは REST の観点からは意味がありません。API のバージョン自体は HTTP 1.0 または 1.1 であり、すでに HTTP リクエスト内で送信されています。この REST リソース中心のビューは、SOAP や Java インターフェイス (修飾名で API バージョンを持つのが一般的) などの他の API インターフェイスとは大きく異なります。
REST では、バージョン管理が意味をなす唯一のことは、そのリソースの表現です (例:新しいフィールドが追加または削除されます)。このバージョン管理は、次のようなコンテンツ ネゴシエーションの一部に属します。
http://xxx/user/123 + HTTP 'Accept' Header -> Content negotation through header
http://xxx/user/123?v=1 -> for perma-links/hyperlinks
このようなバージョンのコンテンツ ネゴシエーションがパス内の URI の一部である可能性があると主張する人もいますが、これは直観に反すると思います。同じリソースに対して異なる URI が使用される可能性があり、ある時点でリダイレクトを維持する必要があるからです。
総括する:REST URI では、API のバージョン管理はなく、リソースの表現のバージョン管理のみが行われます。表現 version-info は content-negotiation (queryParam または HTTP 'Accept' として) に属します。
どう思いますか?どの点に反対/同意しますか?
解決
私は完全に同意します。 URIは、新しいバージョンが導入されたときにIDが変更されない、アイデンティティを表現しています。そこもちろん、追加の概念のための新しいURIのかもしれない、と既存のURIがリダイレクトかもしれません...しかし、URIで「V2」を含むことは私にRPCishを匂います。
それはすべてただの文字だRESTの観点から、これは、本当に、RESTとは何の関係も持っていないことに注意してください。
他のヒント
は、<全角> はX-API-Version
のHTTPリクエストヘッダをリッスンできます。ヘッダが存在する場合、サーバーはAPIのバージョンを使用する必要があります。ヘッダーが存在しない場合は、サーバーはAPIの最新バージョンを使用することができます。
> GET /user/123 HTTP/1.1
> Host: xxx
> X-API-Version: >=1.5.1, <2.0.0
> Accept: application/json
>
< HTTP/1.1 200 OK
< X-API-Version: 1.6.12
<
< { "user": { "id": 123, "name": "Bob Smith" } }
<
それは価値があるものについては、私はマヌエルあなたに同意します。あなたはどのバージョンRESTのURIする
に、この質問に私の推論を見ることができます同意するが、私は心配しないだろうように見える人々がたくさんあります。どのようなあなたのURLは本当にのように見えることは限り、あなたはハイパーテキスト制約を尊重するとして、あなたのクライアントに大きな影響を持っていません。
API で提供されるリソースの URI にバージョンを表示したくないという意見に同意します。それは彼らを「クール」にしないのです。また、変化する可能性が最も高いのは表現であるということにも同意します。
ただし、特定の表現の内容を変更すると何が起こるかという疑問が生じます。たとえば、フロブニッツの元の JSON 表現が次の場合、
{"x": "bam", "y": "hello"}
「z」フィールドを追加したい場合、クライアントは現在、ある種のデータ スキームのバージョン 2 を使用していることをある程度認識する必要があると感じるかもしれません。
そのことはよくわからない。いくつかの選択肢があると思います。
- クライアントの表情を柔軟に変化させ、表現を柔軟に変化させます。上の例では、まだ JSON 辞書を生成しています。
- 必要に応じて、表現自体にバージョンを入力します (この例ではバージョン フィールド)。そうすることで、JSON コンテンツ タイプ内でサブ表現を効果的に宣言することになります。ただし、それはかなり制限的だと思います。
- 独自の MIME タイプを使用し、バージョンを付けます。application/x-my-special-json1.0、application/x-my-special-json1.1。これにより、表現を互いに独立してバージョン管理できるようになります。繰り返しますが、これでは、何が起こっているのかを知るためにクライアントに大きな要求をすることになります。
一般に、自分で開発したものではないクライアント向けに API と表現を最適化したいと思います。あなたのリソースを発見したときに他の人が作成するもの。これは、システムをより堅牢にするのに役立つ有用な設計制約を組み込むため、プライベートなものを作成する場合でも役立つと思います。
私はます。http見つける:// XXXX / V1 /ユーザー/ 123 に それはことを示唆していると混乱が いつか上位のAPIバージョンになります 以下のようなます。http:// XXXX / V2 /ユーザー/ 123 の
それはそれを示唆していない - あなたが将来的にその能力を持っているが、
。しかし、これはRESTで意味がありません。 用語、APIバージョン自体はHTTPです 既にHTTPリクエストの内部に送られる。
1.0または1.1、
YOUR APIのバージョンとあなたが要求が同じである必要はありません作るために使用されているHTTPのバージョン。
あなたが実証されているようです。1つはまた、このようなバージョンと主張している可能性があり コンテンツネゴシエーションはの一部であってもよいです パス内のURIが、私はそれを見つけます 直感的、あなたは可能性があるため、 以下のためのさまざまなURIとエンドアップ 同じリソースおよび維持する必要が いくつかの点でリダイレクトします。
その大丈夫は、URIパラメータとしてバージョンを持っています
ます。http:// xxxの/ユーザー/ 123 V = 1 の - >パーマのために? -links /ハイパーリンク
別のアプローチは、「1つの表現は、複数のAPIを持っている」と言うことは可能性があります:
http://xxx/user/123/api/1.json
そして、あなたが望むなら、あなたはこのように要求して、最新のAPIを使用して表現を返すことができます:
http://xxx/user/123.json
個人的に私は、より良い他のソリューションを好むが、これは、私はまだここで提案見ていない別のアプローチです。
RESTのために、どのようなほとんどの答えは忘れて、データ要素です。私は、複数のバージョンのAPIはまだその同じデータ層を共有だと仮定します。これは、データ層を使用すると、下位互換性のある方法で考えることを強制することを意味します。下位互換性のある方法であなたのAPIが変更された場合に行われなければならビッグ変更は可能です。実際には、これは何かが削除されますことを示すために、あなたのAPIドキュメントに日付で廃止を使用しながら、追加のプロパティは、あなたのエンティティに静かに追加されたことを意味します。理想的にはあなたが特定のスコープ(ラフェイスブック).Therefore以内に廃止についてのそれらを知らせることができますので、私はあなたがどこかのバージョンを指定する必要はないと思います。