HATEOAS を使用して RESTful Web サービスを設計する際に、リンクを完全な URL (" http://server:port/application/customers/1234 ") とパスのみ ("/application/顧客/1234")?
9 に答える
人々が「相対 URI」と言うとき、微妙な概念上のあいまいさがあります。
RFC3986 の定義によると、汎用 URI には以下が含まれます。
URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
hier-part = "//" authority path-abempty
/ path-absolute
/ path-rootless
/ path-empty
foo://example.com:8042/over/there?name=ferret#nose
\_/ \______________/\_________/ \_________/ \__/
| | | | |
scheme authority path query fragment
注意が必要なのは、スキームと権限が省略されている場合、「パス」部分自体が絶対パス (で始まる/
) または「ルートのない」相対パスのいずれかになる可能性があることです。例:
- 絶対 URIまたは完全なURI:
"http://example.com:8042/over/there?name=ferret"
- そして、これは絶対パスを使用した相対 uriです。
/over/there
- そして、これは相対 uri であり、相対パスは:
here
または./here
または../here
または などです。
したがって、質問が「サーバーが安静応答で相対パスを生成する必要があるかどうか」である場合、答えは「いいえ」であり、詳細な理由はここで入手できます。「相対URI」に反対するほとんどの人(私を含む)は、実際には「相対パス」に反対していると思います。
実際には、ほとんどのサーバー側 MVC フレームワークは、などの絶対パスを使用して相対 URI を簡単に生成できます。問題は、「サーバーの実装が絶対パスの前に/absolute/path/to/the/controller
a をプレフィックスする必要があるかどうか」です。scheme://hostname:port
OPの質問のように。これについてはよくわかりません。
一方では、サーバーが完全な uri を返すことをお勧めします。ただし、サーバーは、このようなソース コード内のものをハードコードするべきではありませんhostname:port
(そうでなければ、絶対パスを使用して相対 uri にフォールバックします)。解決策は、サーバー側で常に HTTP リクエストの「ホスト」ヘッダーからそのプレフィックスを取得することです。ただし、これがすべての状況で機能するかどうかはわかりません。
一方、 とhttp://example.com:8042
絶対パスを連結することは、クライアントにとってはさほど面倒ではないようです。結局のところ、クライアントはサーバーにリクエストを送信するときに、そのスキームとドメイン名をすでに知っていますよね?
全体として、絶対URIを使用することをお勧めします。絶対パスを使用して相対URIにフォールバックする可能性があり、相対パスを使用しないでください。
誰がクライアント コードを書いているかによって異なります。クライアントとサーバーを作成している場合、大きな違いはありません。クライアントまたはサーバーで URL を構築するという苦痛に苦しむことになります。
しかし、あなたがサーバーを構築していて、他の人がクライアント コードを書くことを期待している場合、完全な URI を提供すると、彼らはあなたをもっと気に入ってくれるでしょう。相対 URI の解決は少し難しい場合があります。まず、それらをどのように解決するかは、返されたメディア タイプによって異なります。HTML にはベース タグがあり、XML はxml:base
すべてのネストされた要素にタグを持つことができ、Atom フィードにはフィード内のベースとコンテンツ内の別のベースを持つことができます。ベース URI に関する明示的な情報をクライアントに提供しない場合、クライアントはリクエスト URI から、またはおそらくContent-Location
ヘッダーからベース URI を取得する必要があります。そして、末尾のスラッシュに注意してください。ベース URI は、最後のスラッシュの右側にあるすべての文字を無視することによって決定されます。これは、相対 URI を解決するときに、末尾のスラッシュが非常に重要になったことを意味します。
少し言及する必要がある他の唯一の問題は、ドキュメントのサイズです。各アイテムに複数のリンクが含まれるアイテムの大きなリストを返す場合、絶対 URL を使用すると、エンティティを圧縮しないとエンティティに大量のバイトが追加される可能性があります。これはパフォーマンスの問題であり、ケースバイケースで重要かどうかを判断する必要があります。
唯一の本当の違いは、クライアントが相対バージョンから構築するのではなく、絶対 URI を使用する方が簡単だということです。もちろん、その違いは私が絶対バージョンを実行するのに十分です.
アプリケーションの規模が拡大するにつれて、ロード バランシングやフェールオーバーなどを実行したい場合があります。絶対 URI を返す場合、クライアント側のアプリはサーバーの進化する構成に従います。
絶対 URI を使用する場合の欠点の 1 つは、API をプロキシできないことです。
それを取り戻せ... 真実ではありません。ドメインを含む完全な URL を指定する必要があります。
長所については、(絶対) パスのクライアントが必要とする追加の処理を犠牲にして、送信されるバイト数が削減されることがわかります。すべてのバイトを節約したい場合は、gzip としてのコンテンツ エンコーディング、キャッシング ヘッダーの適切な使用、etag の使用、およびクライアントでの条件付きリクエストを試した後でも、最終的にはこれが必要になる可能性がありますが、はるかに高いリターンが期待できます。あなたの努力はそうではありませんでした。
短所については、将来リソース間でクライアントのフローをどのように管理するか (ロード バランシング、A/B テストなど) に関する制御が失われることがわかります。これは、Web の管理に関する悪い習慣だと思います。 API。あなたが提供する URL は、もはや基本的にクライアントにとって不透明ではありません (Tim Berners-Lee Axioms of Web Architecture on URI opacity を参照してください)。最終的には、たとえそれが URL 空間の構造だけに関するものであっても、API の創造的な使用法に関してクライアントを満足させ続ける責任があります。明示的に定義された URL の変更を許可する必要がある場合は、ハイパーテキスト アプリケーション言語で使用されているURI テンプレートの使用を検討してください。