レストデザイン-複数の呼び出しと1つの呼び出しですべてのデータを返す


8

AndroidアプリのREST APIを構築しようとしています。私が持っていると仮定usersして、テーブル(id, name, email)songsを持つテーブルを(id, song_name, album)、豊富なとして、それらの間の関連を参加しstreamsました(user_id, song_id, listen_count)。すべてのストリームの詳細を取得して、アプリにリストとして表示したい。リストには、曲名、アルバム名、ユーザー名、聴取数が表示されます。私は3つのもっともらしいオプションを見ます-

  1. GET/streamsすべてのリストフェッチsong_idsとをuser_ids。次に作るGET/user/:idして/song/:id、ユーザーと曲の情報を取得するために、各ユーザと楽曲IDのために。
  2. GET/streamsすべてのリストフェッチuser_idsとをsong_ids。次に、すべてのユーザーに関する情報を取得GETする/user?ids=<comma_separated_ids>ために1つ、すべての曲に関する情報を取得するGETためsong?ids=<comma_separated_ids>に1つ。
  3. GET/streams1回の呼び出しですべてを取得します。何かのようなもの -

    [
    
      {
    
        "user_id" : 10,
        "song_id" : 14,
        "listen_count" : 5,
        "user" : {
          "id"     : 10,
          "name"   : "bla", 
          "email"  : "bla",
        },
        "song" : {
          "id"     : 14,
          "name"   : "blu",
          "album"  : "blu"
       }
      },
    ...
    ]
    

オプション3で一回の呼び出しですべてが得られるので、私は誘惑に駆られます。しかし、それは非常に休むことはないと思いますし、スケーラブルではないのではないかと心配しています。オプション2は適切ですが、3回の呼び出しが必要であるため、リストのロードにかなりの時間がかかります。オプション1は残りの部分に従いますが、リストを表示するために多くの呼び出しが必要になるため、モバイルデバイスからの多くの呼び出しは実行できません。

これに対処するために推奨される方法は何ですか?


Rest-likeとsalableは2つの異なるものです。
Robert Harvey

@RobertHarveyどういう意味ですか?
aandis 2015

RESTインターフェースの品質が製品の販売可能性に影響を与えると思われる理由は何ですか?RESTインターフェースを実際に販売していますか?そうでない場合、内部の内容を気にする人はいません。meta.stackexchange.com/q/142353
Robert Harvey

1
REST呼び出しを行うと、かなりのオーバーヘッドが生じます。したがって、特に返されたすべてのデータを使用する場合は、スケーラビリティの観点から3が最良のアプローチである可能性が非常に高くなります。
Robert Harvey

回答:


6

RESTインターフェースを作成する場合、RESTインターフェースの応答がデータベースのテーブルまたは結合に直接対応するという要件はなく、期待もされません。

あなたの/streamsインターフェースは、

[
  {
    "listen_count" : 5,
    "user" : {
      "href"     : "/users/10",
      "name"   : "bla", 
    },
    "song" : {
      "href"     : "/songs/14",
      "name"   : "blu",
      "album"  : "blu"
    }
  },
  ...
]

JSONオブジェクトには、ストリームリソースのコンシューマーに(ほぼ)常に関連するユーザーと曲の主な詳細、および詳細が必要な場合は関連するユーザー/曲リソースへのリンクが含まれます。

これは基本的に3番目のオプションのバリエーションであり、詳細が必要な場合はオプション1にフォールバックします。


私に対する保証された答えはありません。ドメインが単純なままである場合、オプション3は単純かもしれませんが、3レベル以上の凝集を見るオブジェクトに対しては問題が発生します。たとえば、教師のデータを含むすべての利用可能なコースを取得するとします。あなたはCourse-> Teacher(別のテーブルに保存されている教師としての人に関する情報)-> Person(同じ人が複数のコースの教師である可能性があることを思い出すことができるので、実際の人)を持っています。オプション2はスケーラブルで、リクエストが必要です。また選ぶ。1もスケーラブルですが、>>リクエストが必要になる可能性があります。
ビクター

したがって、上記のコメントを総合するには、効率を求めている場合は1を目指しますが、問題なく時間をかけて問題なく拡張できるシステム(スケーラビリティ)を探す必要がある場合は、オプション1または2を目指してください。これはオプション3に警告しているので、時期尚早optimiizationが...悪の根であることを言及する
ビクター

上記の自分自身を修正する必要があります。「効率を求めている場合は、3を目指して努力してください」
Victor

3

間違いなく、不透明なIDに加えて、各曲とユーザーに関するメタデータGETを返す単一のオペレーションが必要です。

  • あなたが指摘したように、それははるかに簡単です。それは良いことです。
  • あなたのクライアントのための最も一般的な操作の1を作ることである代わりにO(n)の要求の単一のサーバー要求をアプリずっとよりスケーラブル。長期的には、ネットワークが最大のボトルネックになるため、必要以上のリクエストを送信する必要はありません。
  • 追加のREST呼び出しを行うことを除いて、ID自体は少し役に立たない。
  • メタデータが比較的小さく、制限されたサイズである限り(たとえば、説明テキストのページや実際のオーディオファイルはなく、名前、タイプ、カウントなど)、IDに加えてメタデータを返すことは、パフォーマンスの問題になる可能性は低いです。

面白い。しかし、オプション3は実際にはrest-fullデザインに準拠していませんか?GETするstreams 必要があるすべて返すstreamsと何もないが(彼らは単にIDとクライアントに役に立たない場合でも)。
aandis

2
@zack厳密に言うと、そうですが、設計の原則はあまりにも遠くにあります。プログラム役に立たないことをすべきだと主張する場合、それは通常良い兆候ではありません。
Ixrec

メタデータはデータに関するデータであり、これは単なるデータです。
Jacob Raihle、2015

@zack:streamsリソースは他のリソース(の一部)を論理的に含むことができます。論理的にリソースの一部であるものは、そのリソースの表現に存在する必要があります。
Bart van Ingen Schenau 2015

1
@zackオプション3は完全に100%RESTfulです。APIを介して公開するリソースには、DBテーブルやドメインモデルなど、システム内の他のものに関連する要件はありません。Webアプリにとって意味がある場合は、3つのデータベーステーブルと600のリソースを持つことができます。リソースの関係でDBの関係を表す必要はありません。
Cormac Mulhall 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.