web-dev-qa-db-ja.com

REST apiバージョン管理(リソース自体ではなく、表現のみをバージョン管理する)

私は 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 resource中心的なビューは、SOAPまたはJava-interfaces(修飾名にapi-versionsが含まれるのが一般的です)のような他のapi-interfacesとは大きく異なります。

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-versioningはありません。表現version-infoはcontent-negotiationに属します(queryParamまたはHTTP 'Accept'として)。

どう思いますか?どちらに同意しませんか?

51
manuel aldana

同意します; URIはアイデンティティを表し、新しいバージョンが導入されてもアイデンティティは変わりません。もちろん、追加の概念のための新しいURIが存在する可能性があり、既存のURIがリダイレクトする可能性がありますが、URIに「v2」を含めると、RPCishの匂いがします。

RESTの観点から見ると、これはすべて単なる文字であるため、これはRESTとはまったく関係がないことに注意してください。

36
Stefan Tilkov

あなたcouldX-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" } }
<
10
yfeldblum

それが価値があることについて、私はあなたにマヌエルに同意します。あなたはこの質問で私の推論を見ることができます バージョンの方法REST URIs

反対のように思われる人はたくさんいますが、私は心配しません。ハイパーテキストの制約を順守している限り、URLが実際にどのように表示されても、クライアントに大きな影響はありません。

9
Darrel Miller

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と表現を最適化したいと思います。他の人があなたのリソースを発見したときに作成するもの。これは、システムをより堅牢にするのに役立つ便利な設計制約が組み込まれているため、プライベートなものを作成している場合でも役立つと思います。

2
cdent

別のアプローチは、「1つの表現に複数のAPIがある」と言うことです。

http://xxx/user/123/api/1.json

また、必要に応じて、次のようにリクエストすると、最新のAPIを使用して表現を返すことができます。

http://xxx/user/123.json

個人的には他のソリューションの方が好きですが、これはまだ提案されていないアプローチの1つです。

1
MPV

http:// xxxx/v1/user/12 いつかより高いapi-versionが http:// xxxx/v2/user/12

それはそれを示唆していません-しかし、あなたは将来その能力を持っています。

しかし、これはREST用語では意味がありません。APIバージョン自体はHTTP 1.0または1.1であり、HTTPリクエスト内ですでに送信されています。

YOUR APIのバージョンと、リクエストを作成するために使用しているHTTPのバージョンが同じである必要はありません。

そのようなバージョンのコンテンツネゴシエーションはパス内のURIの一部である可能性があると主張することもできますが、同じリソースに対して異なるURIになってしまい、ある時点でリダイレクトを維持する必要があるため、直感に反することがわかります。

デモで示したように、バージョンをURIパラメータとして使用してもかまいません。

http:// xxx/user/123?v = 1 ->パーマリンク/ハイパーリンクの場合

1
mr-sk

RESTの場合、ほとんどの回答で忘れられるのはデータ要素です。複数のバージョンのAPIが同じデータ層を共有していると思います。これは、データ層により、下位互換性のある方法で考えることを強いられることを意味します。行う必要がある大きな変更は、APIが下位互換性のある方法で変更された場合にのみ可能です。実際には、これは、APIドキュメントで非推奨の日付を使用して、何かが削除されることを示すときに、追加のプロパティが暗黙的にエンティティに追加されることを意味します。理想的には、APIキーユーザーのメールアドレスを使用して登録スキームを使用し、特定の範囲内(Facebookを含む)でのサポート終了を通知できるようにするため、どこかにバージョンを指定する必要はないと思います。

0
Pepster