本REST vs Too many Requests


8

偽のREST APIを非難する彼自身の記事に関するロイフィールディングのコメントから:

真にRESTfulなAPIはハイパーテキストのように見えます。すべてのアドレス可能な情報単位は、明示的に(たとえば、リンクとID属性)または暗黙的に(たとえば、メディアタイプの定義と表現構造から派生)のいずれかでアドレスを伝達します。クエリ結果は、オブジェクト表現の配列ではなく、要約情報を含むリンクのリストで表されます(クエリはリソースの識別の代わりにはなりません)。

これは、たとえば、最近ログインした100人のユーザーのリストをクエリして、その名前と電子メールを表示する必要がある場合、最初GETに結果のリストをクエリする必要があることを意味します。リンク要素のリストであり、各リンクオブジェクトにはユーザーリソースのURIが含まれます。結果を表示するために必要なデータを実際に取得する前に、さらに 100のGETリクエスト(ユーザーリソースごとに1つ)を行う必要があります。

それは信じられないほど非効率的です。1つまたは2つの要求で必要なデータを取得するための本当にRESTfulな方法は他にありませんか?


1
「概要情報付き」という部分を見逃していませんか?
Lucフランケン

1
見逃しませんでしたが、「概要情報」とは「すべてのデータ」ではなく「概要」を意味します。彼は具体的に「オブジェクト表現の配列ではない」と言っています-これはまさに私たちの表示に必要なものです。
ジョナ

1
リストはリソースとして表示され、たとえば、単一のリソースへのリンク、タイトル、短い説明、コメント数などのフィールドが含まれています。オブジェクトが大きすぎるため、完全なオブジェクトは含めません。したがって、リストのリソースは、それを使用するために必要なすべての情報を完全に提供します。さらに多くの情報が必要な場合は、フォーム、大量のコンテンツ、その他の大きなパーツを含む可能性があるリソース全体をロードします。私たちは一度、すべてのリソース(YAGNIの思考プロセス)を完全に含めることを試みましたが、故障しました。そこで、このステップを追加しました。そして、それは完全にRESTだと思います。情報のリストはそれ自体がリソースです。
Luc Franken

RESTに関する厳密な(盲目的な)Fielding文を適用しないでください。もちろん、彼はRESTアーキテクチャの父ですが、注意してください。RESTアーキテクチャはスケーラビリティの高いシステム用であり、それがWebから推論された理由です。パフォーマンスの問題のためにオブジェクトの配列を使用することが理にかなっている場合は、それを実行してください。
AilurusFulgens

HAL + jsonは一般にRESTfulと見なされます。オブジェクトのスリム化されたバージョン(概要)と完全なリソースへのリンクの両方が含まれています。
RubberDuck 2016

回答:


7

1つまたは2つの要求で必要なデータを取得するための本当にRESTfulな方法は他にありませんか?

  • あんまり
  • しかし、それを考えすぎないでください

いつものように、RESTについて考えるときは、チェックできる参照実装(World Wide Web)があることに注意してください。

Amazonポータルについて考えてみます。空のキャッシュでそのブックマークを開くと、ブラウザーが275個のリソースにリクエストを出しているのがわかります。

その状態のすべてが単一のペイロードでフェッチされた場合、レイテンシが向上しますか?はい。

それはスケーリングしますか?それはウェブスケールでしょうか?おそらく違います。これには、自分のプロファイルに固有の1KBが含まれているため、共有できない4.5MBのデータです。私の隣のデスクにいる私の同僚もAmazonに行くと、彼女は同じデータをネットワーク経由で引き出します。

そのペイロードを個別にアドレス指定可能なリソースに分解すると、突然物事が大幅に改善されます-私たちはそれぞれ1KBのパーソナライゼーションを取得し、それぞれにローカルにキャッシュされた4.5MBのコピーを持っていますが、ネットワークを強打する必要はありませんでしたなぜなら、ほとんどのリクエストはインターネット経由でルーティングする必要がなく、ローカルの共有キャッシュによって処理されたからです。

また、実際には複数のリソースに問題があるわけではなく、複数のリクエストに問題があることに注意してください。これは、キャッシュ可能な表現をサーバーが積極的にプッシュするHTTP / 2.0 Push Promisesを使用して軽減できます。たぶん-ステートレスサーバーはクライアントが何をキャッシュしたかを認識しておらず、TLSは中間でのキャッシュが優先事項ではないことを示唆しています...

つまり、たとえば、最近ログインした100人のユーザーのリストをクエリして、その名前と電子メールを表示する必要がある場合、最初に結果のリストに対してGETクエリを実行する必要があります。 )リンク要素のリストであり、各リンクオブジェクトにはユーザーリソースのURIが含まれます。結果を表示するために必要なデータを実際に得る前に、さらに100個のGETリクエスト(ユーザーリソースごとに1つ)を行う必要があります。

もちろん、これをhtmlで行っている場合、最後にログインしたユーザーの表現は、おそらく名前と電子メールアドレスのリストまたはテーブルとそれらのリソースへのリンクを含むドキュメントになります。たーだ。

フィールディングによるこの観察を見失わないでください。

だからといって、RESTのアーキテクチャスタイルに基づいて独自のシステムを設計する必要があるとは思いません。RESTは、複数の組織にまたがる長期間有効なネットワークベースのアプリケーションを対象としています。制約が必要ない場合は、使用しないでください。

編集

JSON表現に対して同じ引数を作成できますか?つまり、問題のリソースがパラメーター化されたクエリの結果ではなく「最後にログインした100人のユーザー」である場合、リソースリンクの代わりにデータ自体を返すことができますか?そうでない場合、なぜですか?この点でJSONが本質的にHTMLと異なるのはなぜですか?

それらがどのように似ているか:より多くのデータを「結果のリスト」にパックすると、スケーリングを妥協しながら、追加のリクエストのコストを節約できます。表現に使用している特定のメディアタイプは関係ありません-少なくとも、私が知る限りでは。

それらがどのように異なるか:HTMLはハイパーメディア形式であり、JSONはそうではありません-HTML仕様に精通しているすべてのbog標準クライアント実装は、プリフェッチなどのオプションをサポートするHTMLドキュメント内のリンクを見つける方法を知っています。JSONにはその標準化がありません。リンクがJSON表現のどこにあるかを理解するには、データ構造に関する帯域外の情報が必要です。 この点で、HALはHTMLに近いものになります。HALとHTMLの主な違いは採用です。HTMLは20年前から始まっていますか?

追加の洞察については、エントリーとフィード(エントリーのリスト)の両方を説明するAtom Syndication Format、特にスタンドアロンリソースまたはフィードリソースを介してアクセスされるかもしれないatom:entryのルールを確認することを検討することもできます。


1
Fieldingによる最後の段落は、すべてのRESTペンダントの額に逆のテキストでステンシルを付けて、ミラーを見るたびに見えるようにする必要があります。
Robert Harvey

いつものように素晴らしい答え。re:HTML表現の最後の段落ですが、JSON表現にも同じ引数を指定できますか?つまり、問題のリソースがパラメーター化されたクエリの結果ではなく、「最後にログインした100人のユーザー」である場合、リソースリンクの代わりにデータ自体を返すことができますか?そうでない場合、なぜですか?この点でJSONが本質的にHTMLと異なるのはなぜですか?
ジョナ

@Jonah JSONはハイパーメディア形式ではなく、HTML(およびその他いくつか)とは対照的です。ハイパーメディア形式では、リンクと関係を記述することができます。HTMLでは、たとえば<a href="URI" rel=""><form method="post">でこれを行います。あなたはアドホックな方法でそれを使用しない限り、JSONでは、あなたは、JSONは、ハイパーメディアについては何も規定していないことができないため(JSONでアドホックハイパーメディア利用状況のいくつかの例を: _link : [ ... ]links : [ ... ] _link_ : [ ... ]、など)(PS:偉大な答え)
AilurusFulgens

@AilurusFulgens、確かに、私はもっと具体的だったはずです。私は「hal + json」(または他のJSONベースのハイパーメディア形式)のようなものを意味しました-質問の主旨は同じです:すべてのデータを含むHTMLで「ドキュメント」を返すのはなぜですか? JSONベースのハイパーメディア形式で同じことをしますか?
ジョナ

編集ありがとうございます。だから私があなたを理解していることを確認するために<ul>、クリック可能なリンクではなく、HTMLテーブルですべての結果を返した場合、hal + json応答で同等のことをしたのと同じように、スケーリングが損なわれるでしょうか?具体的には、おそらく頻繁に変更される返された結果はキャッシュできないため、このような応答はスケーリングされません。一方、リンクのリストはデータが少ないため、取得できない部分は小さくなりますか?それはアイデアですか、それとも私が見逃していることはありますか?
ジョナ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.