REST-Acceptヘッダーを介したコンテンツネゴシエーションと拡張機能のトレードオフ


40

RESTful APIの設計を進めています。特定のリソースに対してJSONとXMLを返したいことがわかっています。私はこのようなことをすると思っていました。

GET /api/something?param1=value1
Accept:  application/xml (or application/json)

ただし、次のように、誰かがこのために拡張機能を使用して投げ出しました:

GET /api/something.xml?parm1=value1 (or /api/something.json?param1=value1)

これらのアプローチのトレードオフは何ですか?拡張機能が指定されていない場合はacceptヘッダーに依存するのが最善ですが、指定されている場合は拡張機能を優先しますか?そのアプローチには欠点がありますか?


使用しているWebサーバーは何ですか?そしてそれはどのようにURLを解析しますか?
ディパンMehta

1
私は物事の技術(サーバー)側については全く知りません。そうは言っても、http標準を使用しているため、理解しやすくなります(たとえば、他の誰かが数年後にメンテナンスを行うことになっている場合)。acceptが指定されていない場合、または予期しない値を持っている場合、拡張機能に依存することができますが、私は常に最初に標準的な方法を使用します。
トレブ

@Dipan MVC4 Web API(まだベータ版)でこれをハッキングしています。ASP.NETのルーティング抽象化を使用しますが、これは非常に便利です。
ブランドンリントン

1
@Trebうん、私はもっと多くのacceptヘッダー値を使うのが好きです。両方をサポートすることに何らかの欠点があるのではないかと思っています。
ブランドンリントン

回答:


38

これは、「しかし、哲学的に-最初のアプローチが唯一のアプローチです。」、そしてこの「適切な公式のRESTfulアプローチはAccept:ヘッダーを使用することです。」され、広く認知ケースのように、だけでなく、ある絶対的に正しくありません

ここに、RESTを定義したRoy Fieldingの簡単なスニペットがあります...

「セクション6.2.1では、コンテンツネゴシエーションを常に使用する必要があるとは述べていません。」引用

その特定の会話は「Accept-Language:」ヘッダーのコンテキストにありますが、「Accept:」ヘッダーにも同じことが当てはまります。

「トップページに2番目と3番目のリンクが表示されない理由がわかりません。

http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

これは2つのPDFエディションを指します。」

彼が意味することは、同じソースデータの異なる表現に異なるエンドポイントを使用しても問題がないということです。(この場合、1つの.htmlエンドポイントと2つの異なる.pdfエンドポイント。)

また、同様の議論で、今回はクエリパラメータを使用することと、異なるメディアタイプのファイル拡張子を使用することの長所について...

「だから私は常に拡張機能を好む。どちらの選択肢もRESTとは何の関係もない。」引用

繰り返しますが、これはAcceptとファイル名の拡張子とはわずかに異なりますが、Fieldingのスタンスは依然として明確です。

回答-それは本当に重要ではありません。2つの間のトレードオフはそれほど重要ではなく、どちらも許容可能なスタイルです。


3
すばらしいバランスのとれた答え。特定のコンテンツが意図されていることは、URIから「明白」であると時々追加すると思う たとえば、URIの.html拡張子または.pdf拡張子。この場合、コンテンツネゴシエーションをサポートする必要は実際にありません。URIにコンテンツを暗黙的に含めると、人間がURIを共有し、すぐに消費できるように物事にリンクするために使用しやすくなります。URIの拡張を避けたい場合や、複数のコンテンツタイプjson / XMLを同等にサポートするWeb APIを公開したい場合など、acceptヘッダーの方が適しています。
ティムラヴェルスミス

新しいリンクを含むように回答を更新しました。ヤフーグループは構造を変えたと思います。
フィルスタージョン14年

同意しません。サーバーによって返されるリソース記述言語は、サービスエンドポイントによって実行されるビジネスロジックとは無関係である必要があります。異なるリソース記述言語に対応するためだけに、同じサービスエンドポイントに複数のURIがあることは、REST URIの構築方法の誤解のように思われます。
デジェイクレイトン

10

適切な公式のRESTfulアプローチは、Accept:ヘッダーを使用することです。

ただし、RESTの要件の1つであるキャッシュ可能性を壊さないように注意する必要があります。Vary: Acceptそれを理解するヘッダーとキャッシュが必要です。理想的な世界ではそれがありますが、実際の生活ではミレージが異なる場合があります。したがって、2番目の解決策はそれほどきれいではありませんが、より実用的かもしれません。

また、一部の非常に古いブラウザはヘッダーを無視し、代わりに拡張機能に依存していたことに注意してください。


1
事実上不正確。受け入れられた回答を参照してください。
フィルスタージョン14年

9

技術的には重要ではありません。Webサーバーは、プロセスを適切に渡すことができます。(私はこれを想定していますが、ショートッパーのようには見えません)。

しかし、哲学的に-最初のアプローチが唯一のアプローチです。RESTでは、URLは実際にはURIのみを指します-これはリソースにすぎません。一瞬のために、この考えてリソースと同じオブジェクトのオブジェクト指向プログラミングでは。あなたはだけで4つのメソッド(別名GET / POST / PUT / DELETE -or何も輸送ができることならば)を介して、このリソースではなく、そのメソッドはなりません。説明オブジェクトのを。同様に、戻り値の側面はURIではありません。オブジェクトはまだ何かであり、something.xmlまたはsomething.jsonではありません

Acceptヘッダーを使用したくない場合でも、哲学的に真のRESTを使用したい場合は、次のようなことは気にしません。

GET /api/something?parm1=value1&return_type=xml

とは対照的に

GET /api/something.xml?parm1=value1 (or /api/something.json?param1=value1)

しかし、私が言ったように、この違いは哲学的なものです。


+1 Dipan、あなたは1つのことを除いて正しい:/ api / something?return_type = xmlはまだ落ち着いていない。RESTfulではない理由は、URLが不透明だからです。IOWは、プロトコルの観点から、/ api / something / xmlと/ api / something?xmlの間に違いはありません。w3.org/DesignIssues/Axioms.htmlを参照してください。
マークE.ハーセ

0

@vartec:あなたは間違っていると思う

適切な公式RESTful原則は、公開または参照されるのはURIであるため、HTTPヘッダーには何も隠してはならないこと、要求/応答に関する詳細はURIの一部として提供することです

したがって、リクエストとレスポンスに関する詳細にヘッダーを使用しないことを強くお勧めします

 GET /api/something.xml?parm1=value1 (or /api/something.json?param1=value1)

参照をすばやく見つけることはできませんが、私はそれらを投稿します(実際には、O'reillyの出版書「RESTful web services」(http://shop.oreilly.com/product/9780596529260.do)を参照できます)同じことを確認します


17
-1完全に間違っています。まず、URL HTTPヘッダーで送信されます。さらに、各個別のURLは個別のリソースを表す必要があります。同じコンテンツのXMLおよびJSONエンコーディングは、明らかに2つの異なるリソースではありません。それらは同じリソースの2つの異なる表現です。
マークE.ハーセ

HTTPヘッダーは、セキュリティクレデンシャル、相関識別子、セッションID、トランザクションコンテキスト、データ形式などの「メッセージングメタデータ」を保存するための正当かつ推奨される場所です。この種の情報によって、URLやメッセージペイロードが乱雑になることはありません。
パウロマーソン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.