web-dev-qa-db-ja.com

バージョン設定方法REST URI

REST URIをバージョン管理する最善の方法は何ですか?現在、URI自体にバージョン番号があります。

http://example.com/users/v4/1234/

この表現のバージョン4の場合。

バージョンはqueryStringに属しますか?すなわち。

http://example.com/users/1234?version=4

または、バージョニングは別の方法で最もよく達成できますか?

105
Mike Pone

V4はv3とは異なるリソースを識別するため、URI自体(オプション1)の一部にすることをお勧めします。 2番目のオプションのようなクエリパラメータは、resourceではなく、requestに関連する追加の(クエリ)情報を渡すのに最適です。

31
Zef Hemel

URLをバージョン管理しないでください。

  • パーマリンクを破る
  • URLの変更は、インターフェイスを介して病気のように広がります。変化していないが、変化している表現を指す表現をどうしますか? URLを変更すると、古いクライアントが破損します。 URLをそのままにしておくと、新しいクライアントが機能しない場合があります。
  • メディアタイプのバージョン管理は、はるかに柔軟なソリューションです。

リソースがapplication/vnd.yourcompany.user + xmlのバリアントを返していると仮定すると、必要なのは、新しいapplication/vnd.yourcompany.userV2 + xmlメディアタイプのサポートを作成し、v1とv2クライアントは、平和的に共存できます。

RESTfulインターフェースでは、コントラクトに最も近いものは、クライアントとサーバー間で交換されるメディアタイプの定義です。

クライアントがサーバーと対話するために使用するURLは、以前に取得した表現に埋め込まれたサーバーによって提供される必要があります。クライアントが知る必要がある唯一のURLは、インターフェースのルートURLです。バージョン番号をURLに追加するのは、クライアントでURLを作成する場合にのみ値を持ちます。これは、RESTfulインターフェースで行うことを想定していません。

既存のクライアントを破壊するようなメディアタイプの変更が必要な場合は、新しいクライアントを作成して、URLをそのままにしてください。

そして、application-xmlとapplication/jsonをメディアタイプとして使用している場合、これは意味がないと現在言っている読者のために。これらをどのようにバージョン管理するのですか?あなたではない。これらのメディアタイプは、コードダウンロードを使用して解析する場合を除き、RESTfulインターフェイスにはほとんど役に立ちません。コードダウンロードを使用すると、バージョン管理が重要なポイントになります。

191
Darrel Miller

ああ、私は再び古い不機嫌そうな帽子をかぶっています。

ReSTの観点からは、それはまったく問題ではありません。ソーセージではありません。

クライアントは、追跡したいURIを受け取り、不透明な文字列として扱います。必要なものを何でも入れて、クライアントはnoバージョン識別子などのことを知っています。

クライアントが知っているのは、メディアタイプを処理できることです。Darrelのアドバイスに従うことをお勧めします。また、個人的には、安らかなアーキテクチャで使用される形式を4回変更する必要があると、何か深刻な問題を起こしていることを示す巨大な大規模な警告サインが表示され、変更耐性のためにメディアタイプを設計する必要性が完全に回避されると感じています。

ただし、どちらの方法でも、クライアントは理解できる形式のドキュメントのみを処理し、その中のリンクをたどることができます。リンク関係(遷移)を知っている必要があります。したがって、URIに含まれるものは完全に無関係です。

私は個人的に http:// localhost/3f3405d5-5984-4683-bf26-aca186d21c04 に投票します

URIの先頭または末尾にv4を配置する必要があるかどうかを質問するために、さらにクライアント開発者またはシステムに触れる人を防ぐ完全に有効な識別子(そして、サーバーの観点から、バージョン、ただし4つのメディアタイプ)。

21
SerialSeb

URLにバージョンを入れるべきではありません。リクエストのAcceptヘッダーにバージョンを入れるべきです-このスレッドの私の投稿を見てください:

APIバージョン管理のベストプラクティス?

URLにバージョンを貼り付けると、次のような愚かなURLになります。 http://company.com/api/v3.0/customer/123/v2.0/orders/4321/

そして、同様に忍び寄る他の問題の束があります-私のブログを参照してください: http://thereisnorightway.blogspot.com/2011/02/versioning-and-types-in-resthttp-api.html

11
jeremyh

これら(より具体的ではない)SO REST= APIバージョン管理に関する質問:

5
Pete TerMaat

バージョン付きのAPIを作成したかったのですが、この記事は非常に便利です。

http://blog.steveklabnik.com/posts/2011-07-03-nobody-understands-rest-or-http

「APIをバージョン管理したい」という小さなセクションがあります。シンプルでわかりやすいことがわかりました。重要なのは、ヘッダーのAcceptフィールドを使用してバージョン情報を渡すことです。

2
Asma Zubair

RESTサービスを使用する前に認証が必要な場合、APIキー/トークンをAPIバージョンに簡単に関連付けて、内部でルーティングを行うことができます。APIの新しいバージョンを使用するには、新しいAPIキーそのバージョンにリンクされている必要があります。

残念ながら、このソリューションは認証ベースのAPIでのみ機能します。ただし、バージョンをURIから除外します。

2
UberSteve

APIのバージョン管理には4つの異なるアプローチがあります。

  • RIパスへのバージョンの追加:

    http://example.com/api/v1/foo
    
    http://example.com/api/v2/foo
    

    重大な変更がある場合は、v1、v2、v3 ...のようにバージョンを増やす必要があります。

    次のようなコードでコントローラーを実装できます。

    @RestController
    public class FooVersioningController {
    
    @GetMapping("v1/foo")
    public FooV1 fooV1() {
        return new FooV1("firstname lastname");
    }
    
    @GetMapping("v2/foo")
    public FooV2 fooV2() {
        return new FooV2(new Name("firstname", "lastname"));
    }
    
  • 要求パラメーターのバージョン管理:

    http://example.com/api/v2/foo/param?version=1
    http://example.com/api/v2/foo/param?version=2
    

    バージョンパラメータは、APIの使用方法に応じてオプションまたは必須にすることができます。

    実装は次のようになります。

    @GetMapping(value = "/foo/param", params = "version=1")
    public FooV1 paramV1() {
        return new FooV1("firstname lastname");
    }
    
    @GetMapping(value = "/foo/param", params = "version=2")
    public FooV2 paramV2() {
        return new FooV2(new Name("firstname", "lastname"));
    }
    
  • カスタムヘッダーを渡す:

    http://localhost:8080/foo/produces
    

    ヘッダー付き:

    headers[Accept=application/vnd.company.app-v1+json]
    

    または:

    headers[Accept=application/vnd.company.app-v2+json]
    

    このスキームの最大の利点は、ほとんどセマンティクスです。つまり、バージョン管理に関係するURIが散らかっていないことです。

    可能な実装:

    @GetMapping(value = "/foo/produces", produces = "application/vnd.company.app-v1+json")
    public FooV1 producesV1() {
        return new FooV1("firstname lastname");
    }
    
    @GetMapping(value = "/foo/produces", produces = "application/vnd.company.app-v2+json")
    public FooV2 producesV2() {
        return new FooV2(new Name("firstname", "lastname"));
    }
    
  • ホスト名の変更またはAPIゲートウェイの使用:

    基本的に、あるホスト名から別のホスト名にAPIを移動します。同じリソースに対して新しいAPIを構築するだけで呼び出すこともできます。

    また、API Gatewayを使用してこれを行うことができます。

2
Javier C.

バージョン管理にURIを使用する場合、バージョン番号はAPIルートのURIに含まれている必要があるため、すべてのリソース識別子にバージョン番号を含めることができます。

技術的には、REST AP​​IはURLの変更(統一されたインターフェイス制約の結果)によって壊れません。関連するセマンティクス(たとえば、API固有のRDF vocab)が後方互換性のない方法で(まれに)変更された場合にのみ中断します。現在、多くのpplは、ナビゲーション(HATEOAS制約)およびREST応答(自己記述型メッセージ制約)に注釈を付けるためにリンクを使用していないため、クライアントが壊れています。

関連するメタデータと表現の構造を短い文字列に入れても機能しないため、カスタムMIMEタイプとMIMEタイプのバージョン管理は役に立ちません。 Ofc。メタデータと構造は頻繁に変更されるため、バージョン番号も...

したがって、あなたの質問に答えるには、リクエストとレスポンスにボキャブ( Hydraリンクされたデータ )で注釈を付け、バージョン管理を忘れるか、下位互換性のないボキャブの変更によってのみ使用する最良の方法(たとえば、ある単語を別の単語に置き換える場合)。

1
inf3rno

URIの末尾にオプション値としてバージョンを含めます。これは、/ V4のような接尾辞または説明したようなクエリパラメータの場合があります。/V4をクエリパラメーターにリダイレクトして、両方のバリエーションをサポートすることもできます。

1
Paul Morgan

Mimeタイプでこれを行うことに賛成票を投じますが、URLでは賛成しません。しかし、理由は他の人と同じではありません。

一意のリソースを見つけるために、URLは一意でなければなりません(リダイレクトを除く)。したがって、/v2.0 URLで、なぜそうではないか/ver2.0または/v2/または/v2.0.0?あるいは -alphaおよび-beta? (それは完全に semver の概念になります)

したがって、MIMEタイプのバージョンはURLよりも受け入れられます。

0
Yarco