Eine andere Art APIs zu implementieren GraphQL als Alternative zu REST

Autor / Redakteur: David Klassen * / Stephan Augsten |

Facebook GraphQL wirft wesentliche Prinzipien klassischer REST-Architekturen über Bord. Angesichts der zunehmenden Popularität von GraphQL lohnt es sich aber, einen genaueren Blick darauf zu werfen und es gegebenenfalls für eigene Projekte in Betracht zu ziehen.

Anbieter zum Thema

Beispiel für eine lesende GraphQL-Abfrage.
Beispiel für eine lesende GraphQL-Abfrage.
(Bild: adesso AG)

Roy Fielding veröffentlichte seine Dissertation über RESTful Applications im Jahre 2000. Heute ist sein Architektur-Stil einer der wichtigsten und am weitesten verbreiteten bei Diensten im Internet. Leider sind REST-basierte Schnittstellen nicht immer optimal auf den jeweiligen Anwendungsfall zugeschnitten.

So kann es zu dem Problem kommen, dass der Client beim Aufruf einer Schnittstelle entweder zu viele oder zu wenige Daten als Response erhält. Bei zu vielen Daten spricht man von Over-Fetching. Bei zu wenigen Daten spricht man dagegen von Under-Fetching, wobei dann mindestens ein weiterer Request notwendig wird, um wirklich alle notwendigen Daten zu bekommen.

Beide Fälle sind schlecht für die Performance der Anwendung, da unnötig große oder unnötig viele Anfragen und Antworten verschickt werden. Je nach Anwendungsfall ist dieser Performance-Verlust mehr oder weniger relevant. Beispielsweise kann es bei mobilen Anwendungen aus diesem Grund zu Verzögerungen kommen.

Eine mögliche Maßnahme gegen dieses Problem ist es, pro Anwendungsfall eine individuelle Schnittstelle zu implementieren, sodass die Größe und Menge der Requests und Responses immer optimal ist. Dies führt allerdings fast immer zu einer unüberschaubar großen Menge an Schnittstellen für die API.

Die Schnittstellen müssen daher zwangsläufig mehr oder wenig generisch entwickelt werden, um eine gesunde Balance zwischen Abstraktion und Menge der Schnittstellen zu erhalten. Under- und Over-Fetching müssen bei diesen generischen Schnittstellen teilweise billigend in Kauf genommen werden.

Query Strings für mehr Flexibilität

Ein weiterer Lösungsansatz für die Minimierung von Under- und Over-Fetching ist die Nutzung von Query Strings. Letztere werden pro REST-Schnittstelle verwendet, um diese flexibler zu machen. So wird beispielsweise in der Abfrage …

/users?select=name,email

… mit dem Query String select die Response einer Benutzerschnittstelle /users auf den Namen und die E-Mail der Benutzer reduziert, um den Payload der Response zu verkleinern. Häufig wird mithilfe dieses Ansatzes gleichzeitig auch das Sortieren, Filtern und Paginieren implementiert. Alle eben genannten Mechanismen wirken dem Over-Fetching entgegen.

Um auch das Under-Fetching mithilfe von Query Strings zu minimieren, kann ein sogenannter include oder expand Parameter verwendet werden. So würde beispielsweise …

/user/2?include=friends

… bewirken, dass die Response der Benutzerschnittstelle für den Benutzer mit der ID 2 nicht nur eine Liste mit Links zu den Ressourcen der Freunde des Benutzers enthält, sondern dessen bereits aufgeschlüsselte Entitäten. Somit werden weitere Anfragen eingespart, falls die Ressourcen der Freunde direkt benötigt werden.

In der Regel steigt mit der Anzahl der Query Strings auch die Komplexität bei der Implementierung. Nicht selten wird an dieser Stelle mühsam eine eigene Abfragesprache entwickelt. Dass hierbei keine Standards existieren (abgesehen von Microsofts Open Data Protocol), macht diese Aufgabe häufig schwierig und fehleranfällig.

GraphQL als Alternativlösung

GraphQL funktioniert prinzipiell ähnlich wie der zuvor beschriebene Lösungsansatz mit den Query Strings. Der Client kann mithilfe einer standardisierten GraphQL-Abfragesprache genau spezifizieren, welche Daten er abfragen beziehungsweise manipulieren möchte.

In GraphQL werden die Daten dabei nicht wie in REST als Ressourcen gesehen, sondern als Knoten, die über verschiedene Relationen (Kanten) miteinander verbunden sind und insgesamt einen Graphen ergeben. Daher auch der Name GraphQL, wobei QL für Query Language (Abfragesprache) steht.

Technisch betrachtet wird bei GraphQL die gesamte API auf eine einzige Schnittstelle reduziert, die alle Anfragen des Clients entgegennimmt. Diese Requests beinhalten jeweils zwei unterschiedliche Arten von GraphQL-Abfragen:

  • Lesende Abfragen
  • Manipulierende Abfragen

Beispiel für eine lesende GraphQL-Abfrage.
Beispiel für eine lesende GraphQL-Abfrage.
(Bild: adesso AG)

Das vorangestellte Beispiel zeigt links eine lesende Abfrage, die den Benutzer mit der ID 42 abfragt und rechts die Antwort des Servers auf diese Abfrage. Es werden der Name, die E-Mail und die Titel seiner Blogbeiträge abgefragt.

Dadurch, dass benötigte Felder explizit angegeben werden können, wird das Over-Fetching verhindert. Ebenso wird das Under-Fetching umgangen, da die Titel der Blogbeiträge nicht in einem weiteren Request angefragt werden müssen, sondern direkt in der ersten Abfrage angeben werden können.

(ID:45487638)