GraphQL ist wie REST vor allem für die Schnittstellen-Definition da. Doch wie schlägt sich GraphQL im Vergleich mit REST?

Die Basics

Beide Standards können über eine Vielzahl an Protokollen genutzt werden. Jedoch werden REST und GraphQL hauptsächlich über HTTP genutzt. Da HTTP weit verbreitet ist, vergleichen wir im Folgenden zunächst die Umsetzung mit HTTP. GraphQL und REST setzen auf menschenlesbare Anfragen und Antworten. Bei beiden Protokollen müssen die Anfragen in HTTP zum Teil speziell kodiert werden.

Endpunkte

Ein Endpunkt beschreibt eine URL, die sich aus verschiedenen Teilen zusammensetzen kann.

In REST werden verschiedene Ressourcen definiert, jede Ressource stellt dabei einen eigenen Endpunkt dar. Auf einer Ressource können wiederum verschiedene Aktionen erlaubt sein. Zu diesen Aktionen gehören meist . Die verschiedenen Aktionen werden dabei durch verschiedene HTTP-Verben unterschieden, so wird für READ beispielsweise GET, für Delete das Delete-Verb genutzt.

In GraphQL hingegen spielen die HTTP-Verben keine Rolle. Hier gibt es auch nur einen einzigen Endpunkt. An diesen Endpunkt wird eine Query gesendet. Ob diese Query per GET oder POST gesendet wird, hängt wiederum von den vom Server angebotenen Methoden ab. Die meisten Server unterstützen GET- und POST-Anfragen. Beide Methoden haben einen Parameter, der die Query beinhaltet. In der Query gibt es dann zwei verschiedene Arten von Wurzelelementen: Queries und Mutations. Mutations sind für Ceate, Update und Delete zuständig. Sie werden jeweils über ihren Namen unterschieden. Hier fällt also die implizite Semantik von REST weg und wird durch explizite Namen ersetzt. Die Queries können einzelne Felder und auch Felder von Feldern abfragen.

Je nach benötigter Logik müssen aber genauso wie in REST die einzelnen Operationen manuell definiert werden.

Queries vs Ressourcen

Die Verwendung von Queries ist einer der Vorteile von GraphQL gegenüber der Verwendung von Ressourcen in REST. In einem REST Interface werden oft viele Daten übergeben. Je länger die API besteht, desto mehr Felder werden erfahrungsgemäß mit der Zeit hinzukommen und desto mehr Daten werden übertragen. Für einige Clients sind vielleicht alle Daten von Interesse, für andere hingegen ist vielleicht nur ein Bruchteil der Daten interessant.

Hier bietet GraphQL die Möglichkeit, über einen Client nur die Daten anzufordern, die der Server wirklich braucht. Das verringert die Datenmenge, die der Client empfangen muss, erheblich. Auch lassen sich mit einer Anfrage bereits Details zu Listenelementen abfragen. Ebenso zu deren Kinderelementen. Und zu deren Kinderelementen. Diese Reihe lässt sich beliebig lange weiterführen. Unter REST müsste mindestens für jede weitere Ebene eine neue Anfrage gestellt werden, wenn die API ungeschickt entworfen wurde, sogar für jedes Element. In einem klassischen REST Interface ist diese Aufgabe mit wesentlich mehr HTTP-Calls verbunden. Ein Beispiel dazu:

{
    me {
        conversations(limit: 30) {
            messages(limit: 1){
                text
               writtenAt
            }
        }
    }
}

Hier werden mit einer einzigen Anfrage die letzten eigenen Conversations und von diesen jeweils die letzte Nachricht mit Text und Erstellzeitpunkt zurückgegeben. Unter REST müssten hier Anfragen für die Conversations und zusätzlich Anfragen für die Messages gestellt werden. In GraphQL hingegen werden alle Daten mit einer Anfrage übermittelt.

Da die einzelnen Anfragen in GQL mehrere verschiedene Daten enthalten, können noch andere Methoden eingesetzt werden, um die Anzahl an Anfragen, die an die Datenbank gehen, zu reduzieren. Aber das behandeln wir später in einem weiteren Blogpost 😉

Zwar kann mit REST Interfaces eine ähnliche Funktionalität umgesetzt werden (z. B. über die Angabe von benötigten Feldern), aber das ist immer mit einem erhöhten Aufwand für den Enwickler und für die Wartung der Anwendung verbunden. In GraphQL ist diese Funktionalität hingegen Standard.

Dokumentation

Wenn wir schon beim Thema Standards sind, in GraphQL ist das Schema grundsätzlich für alle öffentlich zugänglich. Das heißt, jeder Client weiß, welche Möglichkeiten er bei der Abfrage hat. Bei REST Interfaces hingegen gibt es keinen einheitlichen und erzwungenen Standard. Eine Möglichkeit, REST Schnittstellen zu dokumentieren, bietet Open API Specification (OAS, ehemals Swagger). Aber auch dort ist es jedem freigestellt, eine solche Dokumentation zu pflegen. Wenn „richtiges“ REST genutzt wird, bietet HATEOAS eine ähnliche Möglichkeit, hier werden bei einer Anfrage weitere Endpunkte angegeben, die mehr Informationen über die einzelnen Felder zur Verfügung stellen. Jedoch wird dieser Ansatz in den meisten Anwendungen nicht umgesetzt.

Versionierung

Auch bei der Versionierung fällt der Aufwand bei GraphQL geringer aus. In GraphQL können sehr einfach neue Felder hinzugefügt werden. Wenn die Queries sich nicht ändern, bleiben auch Datenmenge und Struktur, die zurückgegeben werden, unverändert bestehen. Bei REST Interfaces werden beim Hinzufügen von Feldern immer auch die neuen Daten mitgegeben. Die Meinung, dass bei GraphQL im Vergleich zu REST nicht mehr versioniert werden muss, stimmt aber nur begrenzt. Wenn „richtiges“ REST eingesetzt wird, ist es durchaus vorgesehen, dass einzelne Felder als „deprecated“ markiert und nach einer bestimmten Zeit entfernt werden können. Damit sind in „echtem“ REST auch keine verschiedenen Versionen nötig. Die gleichen Mechanismen gibt es in GraphQL. Der Unterschied von GraphQL zu REST besteht aber weiterhin darin, dass bei GraphQL neue Felder nicht automatisch zurückgegeben werden. Aber ein häufiger Anwendungsfall in GraphQL sind sogenannte Static Queries, die bereits vorberechnet werden können. Diese Queries profitieren nicht von einer Erweiterung des Datenmodells, da sie auf Serverseite angepasst werden müssen. Vielmehr erhöhen sie den Aufwand, den ein Entwickler leisten muss. Doch diese Queries lassen sich gut cachen.

Caching

Ein weiterer wichtiger Punkt ist das Caching. Zu dem Thema haben wir daher auch schon einen eigenen Blogeintrag vorbereitet. Aber kurz vorne weg: Unter REST können die einzelnen neuen Endpunkte und Ressourcen über ihre URL eindeutig identifiziert und einfach gecacht werden. Unter GraphQL gibt es nur einen Endpunkt, das Caching ist hier aufwändiger.

Subscriptions

Unter REST gibt es für Subscriptions keine standardisierte Methode für Subscriptions. Unter GraphQL gibt es dafür im Standard noch keine Methoden und Schnittstellen, aber z. B. im Apollo Server sind diese Neuerungen bereits enthalten. Damit kann der Server bei Bedarf aktualisierte Informationen zum Client schicken, ohne dass dieser regelmäßig danach fragt. Da sowohl REST als auch GraphQL HTTP nutzen, können solche Lösungen grundsätzlich mit beiden umgesetzt werden. Doch unter GraphQL besteht die Aussicht, dass die Lösungen standardisiert werden, während REST so etwas nicht vorsieht.

Autorisierung

Welcher User welche Daten nutzen darf, kann unter REST auf jedem Endpunkt einfach geprüft werden. Da REST „stateless“ ist, sind alle Informationen, die für die Autorisierung verfügbar sind, immer zwangsweise vorhanden. Unter GraphQL sind nicht alle Informationen in allen Szenarien verfügbar. Lest darüber mehr in unserem Beitrag zum Thema Autorisierung 😊

Ratelimiting

Unter REST ist Ratelimiting kein großes Problem: Ein Client darf jede Stunde 1000 Calls an die API abgesetzt werden. Die Calls können einfach gezählt und ggf. auch unterschiedlich gewichtet werden. Da unter GraphQL jedoch eventuell wesentlich mehr Daten vom Server abgeholt werden als mit einem Aufruf einer REST API, fällt das Thema Ratelimiting hier wesentlich komplexer aus. Auch können in GraphQL die Queries rekursiv erfolgen und sofern sie nicht weiter kontrolliert werden, geben diese unter Umständen so viele Daten zurück, dass der Server lahmgelegt wird „“ also quasi ein DOS Angriff mit einer einzigen Anfrage. Wie dieses Problem gelöst wird, beschreiben wir in unserem Blogeintrag zum Thema Ratelimiting.

Zusammenfassung

REST und GraphQL sind in vielen Punkten verschieden, basieren aber auf den gleichen Technologien und können mit entsprechendem Aufwand die gleichen Funktionalitäten anbieten. Jedoch sind in GraphQL viele der Möglichkeiten standardisiert und werden auch schon umgesetzt, wohingegen unter REST viele Probleme zwar Standardlösungen haben, diese aber nicht erzwungen werden.

GraphQL ist allerdings noch eine sehr neue Technologie, die noch viele Probleme nicht gelöst hat. Auf einige davon werden wir in den nächsten Blogeinträgen noch näher eingehen, andere zeigen sich vielleicht noch. REST bietet an dieser Stelle eine Vielzahl an Tools und Lösungen, die schnell eingebunden werden können und dem Entwickler so eine Menge Aufwand abnehmen, der bei GraphQL dazukommen kann.

Alle Beiträge von Manuel Styrsky

Schreibe einen Kommentar