it-swarm.com.de

Viele kleine Anfragen vs. wenige große Anfragen (API Design)

Ich arbeite derzeit an einem Projekt mit einer Organisation wie folgt:

  • Client - Ruft Daten vom Hauptserver über REST api.
  • Server - Fordert Daten von verschiedenen anderen Servern über APIs von Drittanbietern an
  • APIs von Drittanbietern - Dienste außerhalb meiner Kontrolle, die Daten für den Server bereitstellen (Reddit, Hackernews, Quora usw.)

Nehmen wir zum Zwecke der Argumentation an, der Client benötigt zuerst eine Liste von Elementen aus jeder der APIs von Drittanbietern. Aus dieser Liste wird ein Artikel ausgewählt, an dem der Kunde den vollständigen Inhalt des Artikels sowie die Antworten (d. H. Kommentare) auf den Artikel sehen muss. Ich versuche mich zwischen drei Optionen zu entscheiden:

A la carte

Bei diesem Ansatz hätte ich drei separate Endpunkte auf meinem Server: einen zum Abrufen der Liste der Elemente, einen zum Abrufen des Hauptinhalts für ein Element und einen zum Abrufen der Antworten des Elements.

  • Vorteile: Ich mache nie mehr Anfragen als nötig. Anfragen sollten klein sein, daher sollten sie im Allgemeinen schneller sein.
  • Nachteile: Ich muss viele Anfragen stellen. Nach der Auswahl eines Elements aus der Liste muss der Benutzer möglicherweise warten, bevor der Hauptinhalt angezeigt wird, und dann noch länger warten, bis die Antworten angezeigt werden

Serverseitiger Cache

In dieser Anfrage würde ich meinen Server einmal anrufen, um alle Daten für alle Quellen abzurufen. Die Daten würden dann auf dem Server zwischengespeichert. Der Client hätte dann die gleichen REST Endpunkte wie zuvor, außer dass zwischen den Aufrufen nicht viel gewartet wird, da mein Server bereits über die Daten verfügt und diese nur dem Client zuführen muss.

  • Vorteile: Auf Client-Seite immer noch einfach zu implementieren, jedoch ohne Latenzprobleme
  • Nachteile: Etwas komplizierter auf der Serverseite, und der erste Anruf kann sehr, sehr lange dauern.

Clientseitiger Cache

Dieses Szenario ähnelt dem vorherigen, außer dass der Client immer nur eine Anfrage an den Server stellt: Geben Sie mir alle Daten. Von hier aus liegt es in der Verantwortung des Kunden, die Daten zu speichern und angemessen zu verwenden.

  • Vorteile: Einfache Serverimplementierung, sehr schnell nach dem ersten Anruf
  • Nachteile: Der erste Aufruf erfolgt sehr langsam und komplizierter auf der Clientseite

Ich bin mir nicht sicher, welcher Ansatz der beste ist oder ob mir vielleicht die offensichtliche Lösung fehlt. Jeder Rat wäre sehr dankbar!

57
williamg

Beachten Sie die erwartete Netzwerklatenz (d. H. Ping-Zeit) zwischen Ihren Clients und Ihrem Server. In einer Situation mit hoher Latenz und ansonsten guter Bandbreite werden viele kleine Anforderungen erheblich schlechter als eine große ausgeführt.

Ich habe kürzlich an einem datenbankgestützten Webanwendungsprojekt mit mehreren Teams mitgearbeitet, bei dem sich eines der Teams in Indien befindet (der Rest in den USA). In unserem US-Büro befindet sich eine einzelne Datenbankinstanz, mit der Entwickler unsere lokalen Webserverinstanzen verbinden. Mein Schreibtisch ist vielleicht fünfzig Fuß und zwei LAN-Hops von der Datenbankinstanz entfernt, und die Leistung ist in Ordnung.

Als wir mit den Entwicklern in Indien anfingen, hatten sie enorme Wartezeiten beim Starten der Anwendung und beim Navigieren von Seite zu Seite. Wir reden hier über zehn Minuten Wartezeit. Es stellt sich heraus, dass dies daran lag, dass die ~ 200 ms Ping-Zeit von ihren Schreibtischen zu unserem Entwickler-Datenbankserver mit vielen, vielen kurzen Abfragen an die Datenbank multipliziert wurde. Mein lokaler 0,5-ms-Ping war so trivial, dass das Gespräch zwischen Webserver und Datenbankserver keine Rolle spielte. Dies war das erste Mal, dass wir eine geografische Trennung zwischen Webserver und Datenbankserver hatten.

In unserem Fall bestand die Lösung darin, den Datenbankserver zu klonen und die Kopie in Indien zu erstellen. Dabei ist jedoch zu beachten, dass die Netzwerklatenz mit der Anzahl der Kommunikationen über den gesamten Server multipliziert wird, wenn Client und Server weit voneinander entfernt sind Draht. Die Bandbreite nach dem Verbindungsaufbau ist in der Regel weniger wichtig.

32
JakeRobb

Diese drei Optionen schließen sich nicht gegenseitig aus. Sie können eine Kombination aus clientseitigen und serverseitigen Caches verwenden. Einige Daten, wie z. B. Kommentare, können jedoch veraltet sein, wenn sie zu lange im Cache gespeichert werden. Da Sie nicht überprüfen können, ob dies der Fall ist, sollten Sie es wahrscheinlich überhaupt nicht speichern. Auf der anderen Seite ändert sich der Inhalt normalerweise nicht drastisch, sodass es nicht schaden würde, ihn serverseitig zwischenzuspeichern und dann einen Teil davon auf der Clientseite vorab abzurufen, um die Latenz zu verringern.

2
wfdctrl

Basierend auf nur den Informationen, die Sie gegeben haben, Option 1, weil

  • mit einer einzigen Kundenanfrage würden Sie Äpfel und Orangen mischen und der Obstkorb könnte sehr groß sein.

  • caching ist ein Kompromiss, bei dem Sie an Leistung gewinnen, aber möglicherweise Konsistenz verlieren (veraltete Daten). Wenn Sie keine identifizierten Leistungsprobleme haben, sind Synchronisierungsprobleme normalerweise kein Risiko wert.

1
guillaume31

Ich habe immer ein paar große Anfragen gefunden, um eine bessere Leistung und Skalierbarkeit zu erzielen. Bei allen Ansätzen gibt es jedoch Kompromisse, sodass dies von den Anforderungen des Servers und des Clients abhängt. Möglicherweise möchten Sie eine andere Option verwenden, bei der der Client einen ganzen Bereich oder Datensatz zum Abrufen angibt - nicht unbedingt alle Daten, sondern einen Bereich, der im Laufe der Zeit an die verfügbare Bandbreite angepasst wird.

0
Frank Hileman

Ich würde (fast) Rabattoption 3 wählen. Die Wahl zwischen 1 und 2 hängt von zwei Dingen ab:

  • (A) wie groß das Ergebnis eines einzelnen Gesamtabrufs ist
  • (B) wie viele Details des Ergebnisses der Client/Benutzer normalerweise in dieser Sitzung verwendet.

Es ist einfach, eine Entscheidung zu treffen, wenn A und B Extreme sind:

  • Wenn A groß und B klein ist, wählen Sie auf jeden Fall Option 1 (A la Carte).
  • Wenn A klein und B groß ist, wählen Sie 2 (serverseitiger Cache) oder sogar 3 (clientseitiger Cache).

Für alle anderen A/B-Variationen (groß/klein) müssen Sie Diskretion anwenden. Ich biete oft beide grobe und feine Endpunkte an, um unterschiedliche Anwendungsfälle von verschiedenen Clients zu berücksichtigen.

0
Cornel Masson

Wie immer bei der Programmierung kommt es darauf an.

Die eigentliche Frage lautet also: Was sollten Sie bei der Entscheidung für A/B/C oder eine Kombination der drei berücksichtigen?

Ich würde sagen, dass die wirklichen Unterscheidungsfaktoren die Implementierungsdetails der APIs von Drittanbietern sind, die Sie verwenden. Als Beispiel sollten Sie berücksichtigen: Sind sie schnell oder langsam? Ändern sich Daten häufig und unerwartet? Sind sie "gesprächig" oder ruhen sie sich aus?

Bei schnellen, einfach aufrufbaren Diensten, bei denen sich die Daten so häufig ändern, dass Ihr serverseitiger Cache Probleme mit dem veralteten Cache verursacht, wählen Sie auf jeden Fall Option 1: Mehr Anforderungen, kein Cache, nur bei Bedarf.

Wenn sich Ihre externen Daten auf vorhersehbare Weise ändern oder die Verwendung eingeschränkt ist oder Sie einfach eine bessere Benutzererfahrung beim Zwischenspeichern von Daten auf Ihrem Server erzielen können, gehen Sie zu 2. Beachten Sie jedoch, dass der Cache nicht kostenlos ist: Es hat Kosten in Bezug auf das Debuggen und manchmal beschweren sich Benutzer, dass sie keine Updates sehen.

Option 3 würde ich nur in Betracht ziehen, wenn die Daten nicht viel sind, aber in diesem Fall können sogar die Optionen 1 oder 2 funktionieren, und Sie behalten mehr Logik auf dem Server, sodass ich für 1 oder 2 bleiben würde.

Nur mein 2c.

0
A. Chiesa