paint-brush
Ein neuer Frontend-Hack verbessert die API-Leistungvon@axotion
Neue Geschichte

Ein neuer Frontend-Hack verbessert die API-Leistung

von Kamil Fronczak4m2025/01/17
Read on Terminal Reader

Zu lang; Lesen

In der Vergangenheit verwendeten Entwickler in jedem Fall dieselbe API für Lese- und Schreibvorgänge. Dies führte zu Problemen bei der Optimierung von Indizes für stark abgefragte Felder. Valet-Key-Muster, CQRS und Suchdatenbanken haben dies geändert.
featured image - Ein neuer Frontend-Hack verbessert die API-Leistung
Kamil Fronczak HackerNoon profile picture
0-item

In der Vergangenheit ist mir oft ein gängiger Ansatz aufgefallen, bei dem Entwickler (einschließlich mir selbst natürlich) in jedem Fall dieselbe API sowohl für Lese- als auch für Schreibvorgänge verwendeten. Noch häufiger verließen wir uns für die Verarbeitung beider Vorgänge auf dieselbe Datenquelle, beispielsweise MySQL/PostgreSQL.


Dies bedeutet, dass in dieselben Spalten geschrieben und aus ihnen gelesen wird, was häufig zu Problemen bei der Indexoptimierung für stark abgefragte Felder führt.


So mussten wir beispielsweise häufig Indizes optimieren, um neue Filter zu berücksichtigen oder die Abfrageleistung zu verbessern. Felder, die mit Operatoren wie LIKE verwendet wurden, stellten aufgrund ihrer Auswirkungen auf die Leistung eine besondere Herausforderung dar.


Diese Änderungen führen häufig zu weiteren Anpassungen am Backend, einschließlich der Änderung von APIs, um die aktualisierte Funktionalität verfügbar zu machen, gemessenen Zeiten aufgrund zusätzlicher JOINs und so weiter …


Bildbeschreibung

Um die Herausforderung zu bewältigen, neue Filter und andere Dinge in die API einzufügen, gab es Versuche, den Prozess mithilfe von Tools und Standards wie Apicalypse und natürlich GraphQL zu optimieren.


Diese Lösungen zielten darauf ab, die Generierung von API-Abfragen zu optimieren und den manuellen Aufwand für die Implementierung neuer Filter und Funktionen zu reduzieren und einen dynamischeren Ansatz für die Handhabung des Datenzugriffs zu bieten. Allerdings war die Lernkurve steil.


Bildbeschreibung


Mit dem Aufkommen von CQRS (Command Query Responsibility Segregation) begann sich ein neuer Ansatz abzuzeichnen. Diese Denkweise förderte die Verwendung separater Quellen für Schreib- und Lesevorgänge. Schreibvorgänge konnten Ereignisse ausgeben und Lesevorgänge konnten aus diesen Ereignissen an dedizierten Stellen Ansichten erstellen. Selbst wenn die Lese- und Schreibvorgänge in derselben Datenbank (aber in unterschiedlichen Tabellen) verwaltet wurden, brachte diese Trennung erhebliche Vorteile und konnte natürlich die zweite Herausforderung beseitigen – JOINs und Suchanfragen bei Domänenmodellen, da Lesemodelle üblicherweise in Form von denormalisierten JSONs vorliegen.


Bildbeschreibung

Dies brachte jedoch ein weiteres Problem mit sich. Bei Lesevorgängen mussten wir Schreibvorgänge skalieren, was bedeutete, dass der einzige Grund, warum wir Instanzen unserer Anwendung von X auf Y skalieren mussten, Lesevorgänge waren. Dieses Problem könnte teilweise durch Caching gemildert werden, und in der Welt der Microservices könnten wir dedizierte Microservices für Lesevorgänge haben.


Aber...


Dies war jedoch keine ideale Lösung für andere Architekturstile wie modulare Monolithen, bei denen eine solche Trennung möglicherweise nicht gut mit der Designphilosophie des Systems vereinbar ist. Außerdem war das ganze Produkt ausgefallen, wenn die API ausgefallen war, und wenn man bedenkt, dass die meisten Produkte mehr Lese- als Schreibvorgänge erfordern, konnte dies unnötige Auswirkungen auf das Geschäft haben (natürlich bei Geräten mit ausgefallener API ;) )


Was wäre also, wenn wir diese „Ansichten“, auch Lesemodelle genannt, direkt abfragen könnten, ohne die API einzubeziehen und Lasten zu verarbeiten? Hier kommen Lösungen wie Meilisearch , AppSearch und andere ins Spiel, die ein Muster namens „Valet Key“ nutzen. Durch die Verwendung dieses Musters können Frontends direkt auf leseoptimierte Modelle zugreifen und so die Abhängigkeit von Backend-APIs verringern. Natürlich muss das Frontend die API immer noch nach dem „Valet Key“ „abfragen“, aber das Frontend kann Schlüssel zwischenspeichern, sodass das Frontend auch dann noch kommunizieren und Inhalte anzeigen kann, wenn die API ausgefallen ist.


Bildbeschreibung

Bildbeschreibung


Mit diesem Ansatz können wir uns auf die Lesedatenbank konzentrieren und müssen uns nicht um die Handhabung des Datenverkehrs für Lesevorgänge in unserer API kümmern. Der „Valet Key“, der dem Frontend über unsere API bereitgestellt wird, ist so gesichert, dass das Frontend ihn nicht ändern kann. Er enthält vordefinierte Filter und Indizes.


Wenn das Frontend zusätzliche Funktionen benötigt, kann es diese über die API anfordern, wo die API überprüfen kann, ob sie zugelassen werden. Es sind trotzdem weniger Aufrufe erforderlich.


Einige Vorteile, die ich sehe, sind:

  • Reduzierte API-Last : Entlastet die API vom Leseverkehr, sodass sie sich auf Kernvorgänge konzentrieren kann.
  • Skalierbarkeit : Lesedatenbanken oder Suchdienste sind besser für die Bewältigung hohen Datenverkehrs optimiert, wodurch die Notwendigkeit einer Skalierung des Anwendungs-Backends reduziert wird.
  • Flexibilität : SaaS- oder selbstgehostete Optionen ermöglichen es Teams, die beste Lösung für ihre Infrastruktur auszuwählen.
  • Sicherheit : Vordefinierte Filter und Indizes stellen sicher, dass das Frontend nur auf zulässige Daten zugreifen kann, wodurch Risiken minimiert werden. Schlüssel können durch die API ungültig gemacht werden.
  • Entwicklereffizienz : Reduziert den Bedarf an ständigen API-Updates für neue Filter oder Suchfunktionen.
  • Verbesserte Leistung : Der direkte Zugriff auf leseoptimierte Modelle bietet Benutzern schnellere Abfrageantworten.


Aber es gibt immer auch Nachteile:

  • Endgültige Konsistenz : Aufgrund der Art der endgültigen Konsistenz in Lesemodellen können Daten nach einiger Zeit erscheinen.
  • Zusätzliche Wartung: Führt eine zusätzliche Komponente ein, die überwacht und verwaltet werden muss.
  • Schemakomplexität : Schemata müssen in Code oder an einem gemeinsamen Ort gespeichert werden, da verschiedene Teams aus unterschiedlichen Kontexten möglicherweise dasselbe Dokument ausfüllen müssen (z. B. Mitarbeiter mit E-Mail, aber auch mit verfügbaren Guthaben und Gutscheinen). Obwohl es nicht direkt mit diesem Muster verknüpft ist, erhöht es die Komplexität.
  • Kosten der SaaS-Version oder der selbst gehosteten Wartung


Dieser Ansatz ist also kein Allheilmittel und bringt seine eigenen Herausforderungen mit sich. Wenn Sie jedoch mit den Nachteilen einverstanden sind, erfordert eine kleine Änderung am Frontend wahrscheinlich keine Einbeziehung des Backend-Teams. Dadurch wird der Entwicklungsprozess rationalisiert und die allgemeine Agilität verbessert. Und natürlich sollte auch die Skalierbarkeit einfacher sein.