GraphQL ist sowohl eine Abfragesprache für APIs als auch eine Laufzeitumgebung zur Ausführung dieser Abfragen mit Ihren vorhandenen Daten. Es bietet eine umfassende und klare Beschreibung der in Ihrer API verfügbaren Daten, ermöglicht es Clients, genau das zu erbitten, was sie benötigen, ohne Überflüssiges, erleichtert die Weiterentwicklung von APIs im Laufe der Zeit und unterstützt robuste Entwicklerwerkzeuge.
GraphQL-Zugriffskontrolle und Abfrageoptimierung
Zugriffskontrolle
Authentifizierung ist ein Satz von Regeln oder Geschäftslogik, der bestimmt, ob ein Benutzer, eine Sitzung oder ein Kontext die Zugriffskontrollliste (ACL) hat, um bestimmte Aktionen auszuführen oder spezifische Daten anzusehen.
Ein solches Verhalten sollte auf der Ebene der Geschäftslogik durchgesetzt werden. Während es verlockend sein mag, die Authentifizierungslogik direkt in die GraphQL-Schicht zu legen, ist es im Allgemeinen angemessener, dies anderswo zu handhaben.
Abfrageoptimierung
Die Optimierung von GraphQL-Abfragen umfasst Techniken wie das Minimieren unnötiger Datenabfragen und -verarbeitung, um Antwortzeiten zu verbessern und die Serverlast zu reduzieren. Dies führt zu einer effizienteren Anwendung, die eine bessere Benutzererfahrung, erhöhte Benutzerbindung und -haltequote sowie eine gesteigerte Server skalierbarkeit bietet.
Wege zur Optimierung von GraphQL-Abfragen
- N+1 (Batched Loading)
- Über- und Unterabfrage
- Caching zur Latenzreduktion
- Seitennummerierung
Verbesserung der GraphQL-Zugriffskontrolle und GraphQL-Abfrageoptimierung
Autorisierungs-Engine validiert Knoten- und Felberechtigungen mittels ACL (Zugriffssteuerungsliste) und optimiert GraphQL-Abfragen basierend auf den Berechtigungen. Zusätzlich verbessert der N+1-Resolver die Leistung durch Konsolidierung von Abfragen. Dieser Ansatz adressiert das N+1-Problem.
Akteure
- GraphQL-Abfrage: Eine vom Client an einen GraphQL-Server gesendete Anfrage, um spezifische Daten abzurufen.
- GraphQL-Engine: Bezieht sich auf einen Dienst, der die Ausführung von GraphQL-Abfragen ermöglicht.
- Autorisierungs-Engine: Validiert die Berechtigungen von Knoten und Feldern mittels ACL und optimiert die GraphQL-Abfrage basierend auf Felberechtigungen.
- N+1-Resolver: Reduziert den Overhead und die Latenz, die mit mehreren Datenbankabfragen verbunden sind, und verbessert Leistung und Effizienz.
Zugriffskontrolle verbessern
Bestehende Implementierung
Nehmen wir an, eine App hat Produkte, Anbieter und Adressen. Der Zugriff auf Anbieter- und Adressdaten erfordert Benutzerauthentifizierung, was in Resolvers leicht handhabbar ist.
Allerdings sind die Daten des Anbieters auf Admin-Benutzer beschränkt, und einige Anbieterfelder sind nur für bestimmte Rollen zugänglich. Auf der anderen Seite sind Produkte öffentlich und können mit der Rolle „Produktbesitzer“ angezeigt werden. Das Ausführen der genannten Abfrage (Abbildung 3) gibt Produktdaten zusammen mit zugehörigen Anbieter- und Adressdaten zurück, was zu einem Sicherheitsproblem führt.
Erweiterte Implementierung
Knoten und Felder der Abfrage werden gemäß den Berechtigungen des Benutzers validiert, und eine optimierte GraphQL-Abfrage wird generiert.
Abbildung 4 ist ein Beispiel dafür, wie man eine benutzerdefinierte Authentifizierung in einer GraphQL API mit Node.js implementieren könnte. In diesem Code wird die Rolle aus dem Autorisierungsheader extrahiert und dann zusammen mit der Abfrage zur Validierung der Autorisierung verwendet.
In diesem Beispiel verwenden wir die Rolle und Berechtigung eines Benutzers aus der Sitzung oder Anfrage, die den Zugriff auf bestimmte Abfragen und Mutationen im GraphQL-Schema steuern. Wir haben die Rollen- und Berechtigungssregeln im GraphQL-Schema für alle Benutzer definiert.
Diese Methode prüft rekursiv die Rolle und Berechtigung auf allen Knoten und Feldern. Wenn ein Knoten oder Feld nicht erlaubt ist, führt sie eine der folgenden Aktionen basierend auf der Konfiguration aus:
- Knoten oder Feld entfernen.
- Feld oder Knoten mit einer Fehlermeldung zurückgeben.
- Ausnahme auslösen.
Sobald die GraphQL-Abfrage gegen das Schema validiert wurde, gibt diese Methode die optimierte GraphQL-Abfrage zurück.
Erweiterung der ORM-Abfrageoptimierung mit N+1
Bestehende Implementierung
Es handelt sich um ein technisches Problem, das die Leistung einer Abfrage beeinträchtigt. Es kann in Anwendungen auftreten, die ein Objektrelationales Mapping (ORM) Framework zur Datenbankzugriff verwenden.
Es tritt typischerweise auf, wenn die Anwendung eine Sammlung verwandter Entitäten aus der Datenbank laden muss.
Nehmen wir an, es gibt 2 Produkte; es muss 1 Abfrage durchführen, um die Produkte abzurufen, und 2 zusätzliche Abfragen, um die Anbieter für jedes Produkt einzeln abzurufen.
Eine Abfrage ruft die Liste der Produkte ab, und eine separate Abfrage holt die Anbieter für jedes Produkt. Die Anzahl der Anbieterabfragen entspricht der Anzahl der Produkte.
Erweiterte Implementierung
Sobald die Anfrage den N+1-Resolver erreicht, optimiert der N+1-Resolver die Abfragen, um die Anzahl der Datenbankanfragen zu minimieren, indem er sie auf eine einzige Abfrage für die Hauptdaten und eine zusätzliche Abfrage für verwandte Daten reduziert, wodurch das N+1-Problem effektiv gemildert wird.
- Hauptdatenabfrage: Eine einzige Abfrage, die den Hauptdatensatz abruft, den die Anwendung benötigt.
- Verwandte Datenabfrage: Eine zusätzliche Abfrage, die alle notwendigen verwandten Daten abruft, um den Datensatz zu vervollständigen.
Nachdem alle Abfrage-Resolver abgeschlossen sind, gibt der Server die optimierten Daten im JSON-Format an den Client zurück.
Schlussfolgerung
Wir haben dargelegt, dass die Implementierung feingranularer Autorisierungsmechanismen sowie verstärkter Sicherheitsmaßnahmen entscheidend für die Absicherung einer GraphQL-API ist. Dies umfasst sowohl Node-Level- als auch Field-Level-Sicherheit.
Wie in diesem Artikel beschrieben, tritt das N+1-Problem auf, wenn eine unoptimierte Abfrage zu übermäßigen Datenbankaufrufen in GraphQL führt. Wir haben eine Lösung bereitgestellt, um das N+1-Problem zu überwinden. Es verringert die Ressourcennutzung des Datenbankservers, was zu Kosteneinsparungen und besserer Skalierbarkeit führt. Zusätzlich verbessert die Optimierung der Abfrageleistung das Benutzererlebnis, indem die Antwortzeiten der Abfragen verkürzt werden.
Source:
https://dzone.com/articles/optimizing-fine-grained-graphql-access-control-and-queries