Viele kleine Anforderungen im Vergleich zu wenigen großen Anforderungen (API-Design)


49

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

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

Nehmen wir an, der Client benötigt zunächst eine Liste der Elemente aus jeder API eines Drittanbieters. Aus dieser Liste wird ein Artikel ausgewählt, an dem der Kunde den vollständigen Inhalt des Artikels sowie die Antworten (dh Kommentare) auf den Artikel sehen muss. Ich versuche mich zwischen drei Möglichkeiten zu entscheiden:

A la carte

Bei diesem Ansatz hätte ich drei separate Endpunkte auf meinem Server: einen, um die Liste der Elemente abzurufen, einen, um den Hauptinhalt für ein Element abzurufen, und einen, um die Antworten des Elements abzurufen.

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

Serverseitiger Cache

In dieser Anfrage würde ich einen einzigen Aufruf an meinen Server senden, um alle Daten für alle Quellen abzurufen. Die Daten würden dann auf dem Server zwischengespeichert. Der Client hat dann dieselben 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 an den Client weiterleiten muss.

  • Vorteile: Client-seitig immer noch einfach zu implementieren, jedoch ohne Latenzprobleme
  • Nachteile: Ein bisschen mehr Server-Seite, und der erste Anruf könnte wirklich sehr, sehr lange dauern.

Clientseitiger Cache

Dieses Szenario ähnelt dem vorherigen, mit der Ausnahme, dass der Client immer nur eine Anfrage an den Server sendet: Geben Sie mir alle Daten. Ab hier liegt es in der Verantwortung des Kunden, die Daten zu speichern und entsprechend zu nutzen.

  • Vorteile: Einfache Server-Implementierung, sehr schnell nach dem ersten Aufruf
  • Nachteile: Der erste Aufruf wird eine sehr langsame, kompliziertere clientseitige Implementierung sein

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


Dies scheint mir eine Wahl zwischen Frische und Schnelligkeit zu sein. Was bevorzugen Ihre Stakeholder und Endnutzer?
Erk

Antworten:


27

Eine Sache, die Sie beachten sollten, ist die erwartete Netzwerklatenz (dh die Ping-Zeit) zwischen Ihren Clients und Ihrem Server. In einer Situation mit hoher Latenz und sonst guter Bandbreite sind viele kleine Anforderungen deutlich schlechter als eine große.

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

Als wir mit den Entwicklern in Indien zum ersten Mal anfingen, gab es enorme Wartezeiten beim Starten der Anwendung und beim Navigieren von Seite zu Seite. Wir reden hier zehn Minuten Wartezeit. Es stellte sich heraus, dass dies daran lag, dass die Ping-Zeit von ~ 200 ms von ihren Schreibtischen zu unserem Entwickler-Datenbankserver mit vielen, vielen kurzen Abfragen an die Datenbank multipliziert wurde. Mein lokaler Ping von 0,5 ms war so trivial, dass die Kommunikation 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 sichern. Der springende Punkt hierbei ist jedoch, dass die Netzwerklatenz mit der Anzahl der Kommunikationen über das Internet multipliziert wird, wenn Client und Server weit voneinander entfernt sind Draht. Sobald die Verbindung hergestellt ist, ist die Bandbreite in der Regel weniger von Belang.


2

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 aufbewahrt werden. Da Sie nicht überprüfen können, ob dies der Fall ist, sollten Sie es wahrscheinlich überhaupt nicht aufbewahren. Auf der anderen Seite ändert sich der Inhalt normalerweise nicht drastisch, so dass es nicht schaden würde, ihn serverseitig zu cachen und dann einen Teil davon auf der Clientseite vorab abzurufen, um die Latenz zu verringern.


1

Basierend nur auf den von Ihnen angegebenen Informationen, Option 1, weil

  • mit einem einzigen Kundenwunsch 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 an Konsistenz verlieren (veraltete Daten). Wenn Sie keine identifizierten Leistungsprobleme haben, lohnt es sich normalerweise nicht, Synchronisierungsprobleme zu riskieren.


0

Ich habe immer ein paar große Anforderungen gefunden, die eine bessere Leistung und Skalierbarkeit erfordern. Da jedoch bei allen Ansätzen Kompromisse bestehen, hängt dies von den Anforderungen des Servers und des Clients ab. Möglicherweise möchten Sie eine andere Option verwenden, bei der der Client einen vollständigen Bereich oder einen Satz abzurufender Daten angibt - nicht unbedingt alle Daten, sondern einen Bereich, der im Laufe der Zeit an die verfügbare Bandbreite angepasst wird.


0

Ich würde Option 3 (fast) rabattieren. 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 verwenden wird.

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).

Bei allen anderen A / B-Variationen (groß / klein) müssen Sie nach eigenem Ermessen vorgehen. Ich biete oft sowohl grobe als auch feine Endpunkte an, um unterschiedliche Anwendungsfälle von verschiedenen Kunden zu berücksichtigen.


0

Wie immer bei der Programmierung kommt es darauf an.

Die eigentliche Frage lautet also: Was sollten Sie beachten, wenn Sie sich für A / B / C oder eine Kombination der drei entscheiden?

Ich würde sagen, dass die eigentlichen Unterscheidungsfaktoren die Implementierungsdetails der von Ihnen verwendeten Drittanbieter-APIs sind. Als Beispiel sollten Sie berücksichtigen: Sind sie schnell oder langsam? Ändern sich Daten häufig und unerwartet? Sind sie "gesprächig" oder rasten sie?

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

Wenn sich Ihre externen Daten auf vorhersehbare Weise ändern werden oder Sie mit der Nutzung eingeschränkt sind oder einfach eine bessere Benutzererfahrung beim Zwischenspeichern von Daten auf Ihrem Server erzielen können, fahren Sie mit Schritt 2 fort. 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 groß sind, aber in diesem Fall können sogar die Optionen 1 oder 2 funktionieren, und Sie behalten mehr Logik auf dem Server bei, sodass ich für 1 oder 2 bleibe.

Nur mein 2c.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.