Rest Design - Mehrere Anrufe statt Rückgabe aller Daten in einem Anruf

8

Ich versuche eine Rest-API für eine Android-App zu erstellen. Angenommen , ich habe eine usersTabelle mit (id, name, email)und einen songsTisch mit (id, song_name, album)und eine reiche verbinden Verbindung zwischen ihnen als streamsmit (user_id, song_id, listen_count). Ich möchte Details zu allen Streams abrufen und in der App als Liste anzeigen. Die Liste würde den Songnamen, den Albumnamen, den Benutzernamen und die Höranzahl anzeigen. Ich sehe drei plausible Optionen -

  1. GETauf /streamsund eine Liste aller Abruf song_idsund user_ids. Machen Sie dann GETzu /user/:idund /song/:idfür jeden Benutzer und jede Song-ID, um die Benutzer- und Song-Informationen zu erhalten.
  2. GETauf /streamsund eine Liste aller Abruf user_idsund song_ids. Dann , eines GETzu /user?ids=<comma_separated_ids>holen Informationen über alle Benutzer und GETzu song?ids=<comma_separated_ids>Informationen über alle Songs zu holen.
  3. GETzu /streamsund alles in einem Aufruf zu holen. Etwas wie -

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

Ich bin versucht, Option 3 zu wählen, weil es mir alles in einem Anruf gibt, aber ich denke nicht, dass es sehr ruhig ist und ich befürchte, dass es nicht skalierbar ist. Option 2 ist gut, aber es sind 3 Anrufe erforderlich, was ein erhebliches Laden der Liste bedeuten würde. Und Option 1 folgt auf Ruhe, nimmt jedoch zahlreiche Anrufe entgegen, um die Liste anzuzeigen, und so viele Anrufe von einem mobilen Gerät aus sind nicht möglich.

Was wäre der empfohlene Weg, um dies zu tun?

aandis
quelle
Ruhe und Verkaufbarkeit sind zwei verschiedene Dinge.
Robert Harvey
@ RobertHarvey wie meinst du das?
Aandis
Was lässt Sie glauben, dass die Qualität Ihrer REST-Schnittstelle die Verkaufbarkeit eines Produkts beeinflusst? Verkaufen Sie tatsächlich die REST-Schnittstelle? Wenn Sie nicht sind, kümmert es niemanden, was unter der Haube ist. Siehe auch meta.stackexchange.com/q/142353
Robert Harvey
1
Das Tätigen eines REST-Anrufs ist mit einem erheblichen Aufwand verbunden. Folglich besteht die starke Möglichkeit, dass 3 unter dem Gesichtspunkt der Skalierbarkeit der beste Ansatz ist, insbesondere wenn Sie alle so zurückgegebenen Daten verwenden.
Robert Harvey
1
In
gewisser

Antworten:

6

Beim Erstellen einer REST-Schnittstelle besteht keine Anforderung oder Erwartung, dass die Antworten auf der REST-Schnittstelle direkt Tabellen oder Verknüpfungen in der Datenbank entsprechen.

Ihre /streamsBenutzeroberfläche kann genauso einfach dargestellt werden wie

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

Wobei die JSON-Objekte die Hauptdetails von Benutzern und Songs enthalten, die (fast) immer für Verbraucher einer Stream-Ressource relevant sind, und einen Link zu den relevanten Benutzer- / Song-Ressourcen, wenn weitere Details benötigt werden.

Dies ist im Wesentlichen eine Variation Ihrer dritten Option, mit einem Rückgriff auf Option 1, wenn weitere Details benötigt werden.

Bart van Ingen Schenau
quelle
Es gibt keine garantierte Antwort für mich, Leute ... Option 3 könnte einfach sein, wenn die Domänen einfach bleiben, aber Sie werden in Schwierigkeiten mit Objekten geraten, die mehr als zwei Aggretationsstufen aufweisen. Sie möchten beispielsweise alle verfügbaren Kurse mit Daten des Lehrers abrufen. Sie haben Course-> Teacher(Informationen über die Person als Lehrer, gespeichert in einer separaten Tabelle) -> Person(die physische Person, wie Sie sich erinnern können, könnte dieselbe Person Lehrerin mehrerer Kurse sein). Option 2 ist skalierbar und erfordert eine * Anforderung. Auch opt. 1 ist ebenfalls skalierbar, benötigt jedoch möglicherweise eine >> Anforderung.
Victor
Um den obigen Kommentar zusammenzufassen: Wenn Sie nach Effizienz suchen, dann streben Sie nach Nummer 1, aber wenn Sie nach einem System suchen, das ohne Zeitprobleme (Skalierbarkeit) ohne Kopfschmerzen wachsen kann, streben Sie Option 1 oder 2 an. Es lohnt sich zu erwähnen, dass vorzeitige Optimierung die Wurzel des Bösen ist ... also warnt dies vor Option 3.
Victor
Ich muss mich oben korrigieren. "Wenn Sie nach Effizienz suchen, dann streben Sie nach Nummer 3"
Victor
3

Sie möchten auf jeden Fall eine einzelne GETOperation, die zusätzlich zu ihren undurchsichtigen IDs Metadaten zu jedem Song und Benutzer zurückgibt .

  • Wie Sie betont haben, ist es viel einfacher. Das ist eine gute Sache.
  • Es ist viel skalierbarer, eine der häufigsten Vorgänge für Ihre Client-Apps zu einer einzelnen Serveranforderung anstelle von O (n) -Anfragen zu machen. Auf lange Sicht wird das Netzwerk Ihr größter Engpass sein, sodass Sie nicht mehr Anfragen senden möchten, als Sie müssen.
  • Die IDs selbst sind bis auf zusätzliche REST-Aufrufe nutzlos.
  • Solange Ihre Metadaten eine relativ kleine und begrenzte Größe haben (z. B. keine Seiten mit beschreibendem Text oder tatsächlichen Audiodateien, nur Namen, Typen, Anzahl usw.), ist es unwahrscheinlich, dass die Rückgabe zusätzlich zu den IDs ein Leistungsproblem darstellt.
Ixrec
quelle
Interessant. Aber Option 3 hält sich nicht wirklich an ein rest-fullDesign, oder? Ein GETto streams sollte alles streamsund nichts zurückgeben (auch wenn es sich nur um IDs handelt und für den Client nutzlos ist).
Aandis
2
@zack Im strengsten Sinne ja, aber jedes Designprinzip kann zu weit gehen. Wenn Sie argumentieren, dass das Programm etwas Nutzloses tun sollte , ist das normalerweise kein gutes Zeichen.
Ixrec
Metadaten sind Daten über Daten, dies sind nur Daten.
Jacob Raihle
@zack: Eine streamsRessource kann logisch (Teile) anderer Ressourcen enthalten. Dinge, die logisch Teil einer Ressource sind, sollten in der Darstellung dieser Ressource vorhanden sein.
Bart van Ingen Schenau
1
@ Zack Option 3 ist vollständig 100% RESTful. Die Ressourcen, die Sie über Ihre API verfügbar machen, müssen sich nicht auf andere Elemente in Ihrem System beziehen, einschließlich Ihrer DB-Tabellen und Ihres Domänenmodells. Sie könnten 3 Datenbanktabellen und 600 Ressourcen haben, wenn dies für Ihre Web-App sinnvoll wäre. Es ist nicht erforderlich, Ihre DB-Beziehungen in Ihren Ressourcenbeziehungen darzustellen.
Cormac Mulhall