Brian Jackson - Fotolia

So entscheiden Sie zwischen REST und gRPC

REST APIs und JSON- oder XML-Dateien können zu Flaschenhälsen in der Architektur werden. Hier könnte gRPC gegebenenfalls eine gute Alternative für die IT-Umgebung darstellen.

Trotz der weit verbreiteten Akzeptanz von REST als De-facto-Standard für die Entwicklung von Webdiensten weist das API-Protokoll einige bedeutende Mängel auf. Die Formate für den Datenaustausch können übermäßig komplex sein, und es mangelt an einheitlichen Standards für die API-Dokumentation und -Veröffentlichung.

Eine vielversprechende Alternative zu REST ist gRPC. Dieses moderne RPC-System (Remote Procedure Call) nutzt innovative Verfahrenstechniken, um die Kommunikation in verteilten Client-Server-Architekturen besonders effizient zu gestalten. gRPC bietet beim Design von Webservices Funktionen, die nicht nur die Leistung verbessern, sondern auch Interaktionen standardisieren und die Entwicklung von Microservices berechenbarer machen.

In diesem Artikel wird die Debatte zwischen REST und gRPC analysiert und dargelegt, warum Entwicklungsteams gRPC in Betracht ziehen sollten.

Was REST so populär macht 

In der heutigen Entwicklungslandschaft ist es üblich, dass Unternehmen öffentliche REST APIs bereitstellen, die in Anwendungen von Drittanbietern integriert werden. So veröffentlichen beispielsweise renommierte Organisationen wie die New York Times und das US-Handelsministerium weit verbreitete REST APIs, die extern genutzt werden.

Trotz dieser Popularität hat REST jedoch mit Herausforderungen zu kämpfen, insbesondere hinsichtlich der Standardisierung, des Leistungs-Overheads und der Streaming-Fähigkeiten für Web-Service-Clients. Hier kommt gRPC ins Spiel.

gRPC, entwickelt von Google, ist ein API-Protokoll, das speziell für Anwendungen konzipiert wurde, die Daten schnell und kontinuierlich abrufen müssen. Obwohl gRPC in der Anwendung komplexer ist als REST, rechtfertigen die potenziellen Vorteile eine intensivere Auseinandersetzung mit diesem Protokoll.

Die Funktionsweise von REST

Representational State Transfer (REST) ist ein spezifischer Architekturstil, der HTTP als Standardkommunikationsprotokoll für Ressourcen nutzt, die durch APIs definiert werden. Eine Ressource kann als eine Entität betrachtet werden, ähnlich einem Objekt in der objektorientierten Programmierung (OOP).

Wie ein Objekt in der OOP verfügt auch eine RESTful-Ressource über Eigenschaften und Verhaltensweisen. Viele REST-Implementierungen konzentrieren sich jedoch hauptsächlich auf die Eigenschaften einer Ressource und berücksichtigen das RESTful-Verhalten nur unzureichend. Implementierungen, die eine RESTful-Ressource ausschließlich in Bezug auf ihre Eigenschaften beschreiben, gelten als RESTful.

HTTP und REST APIs

Unter REST wird eine Ressource oder eine Sammlung von Ressourcen durch eine URL beschrieben. Die folgende Beispiel-URL beschreibt eine Sammlung von Tier-Ressourcen, die über eine fiktiv benannte API auf example.com verfügbar sind.

https://api.example.com/tiere

REST macht sich die HTTP-Spezifikation zunutze, um das Abrufen, Hinzufügen, Ändern und Löschen einer Quelle in einem bestimmten Bereich mit Hilfe der HTTP-Verben GET, POST, PUT, PATCH und DELETE zu realisieren. Die folgende Tabelle 1 zeigt die von Entwicklern am häufigsten verwendeten HTTP-Methoden.

Abbildung 1: Es gibt einige HTTP-Methoden, die besonders häufig genutzt werden.
Abbildung 1: Es gibt einige HTTP-Methoden, die besonders häufig genutzt werden.

RESTful-Ressourcen

Wenn Sie – unter Verwendung der oben beschriebenen Tier-Ressourcen – alle in der API unter api.mysimpleapi.com verfügbaren Tiere mit Unterstützung des Befehlszeilenprogramms curl abrufen möchten, müssen Sie folgende Anweisung in einem Terminalfenster ausführen:

curl https://api.mysimpleapi.com/tiere

Wenn Sie der API ein Tier hinzufügen möchten, könnten Sie mit curl eine POST-Anfrage an die API stellen, etwa so:

curl -d ' {"Spezies": "Hund", "Rasse": Poodle, "Beine": 4 }' -H "Content-Type: application/json" -X POST

https://api.mysimpleapi.com/tiere

Wichtig ist es dabei, zu verstehen, dass die REST-Architektur für den Informationsaustausch HTTP als Mittel für Anfragen an eine REST-API verwendet. Entwickler können Daten mit den Standard-HTTP-Methoden GET, POST, PUT, PATCH und DELETE abrufen, hinzufügen, ändern und löschen.

Formate für den Datenaustausch von Webdiensten

REST ist schon seit Jahrzehnten im Einsatz. Im Laufe der Zeit hat sich eine bestimmte Konvention für die Definition von URLs herausgebildet. In der Regel beschreibt die Basis-URL für eine Ressource die Sammlung von Ressourcen, zum Beispiel:

/tiere/

Dieser URL-basierte Verweis auf eine RESTful-Ressource gibt alle Tier-Ressourcen in einem Datenaustauschformat wie JSON zurück:

[

{ "id": 501, "Spezies": "Hund", "Rasse": "Terrier", "Beine": 4 },

{ "id": 502, " Spezies ": "Vogel", "Art": "Robin", " Beine ": 2 },

]

Das herkömmliche Format zum Abrufen einer bestimmten Ressource innerhalb der Sammlung besteht darin, den eindeutigen Bezeichner der jeweiligen Ressource als Teil der URL-Definition festzulegen, etwa so:

/tiere /{id}

Dabei ist {id} der Platzhalter für den tatsächlichen eindeutigen Bezeichner.

Um also ein bestimmtes Tier über die API von example.com abzurufen, wird die URL wie folgt geschrieben:

https://api.mysimpleapi.com/tiere/501

Das Ergebnis einer GET-Anfrage an die fiktive Animals-API unter der oben angegebenen URL lautet dann:

{ "id": 501, "Spezies": "Hund", "Rasse": "Terrier", "Beine": 4 }

Abbildung 2 zeigt die Details zum Abrufen einer bestimmten Ressource.

Abbildung 2: Bildliche Darstellung einer REST-basierten Interaktion zwischen Client und Server.
Abbildung 2: Bildliche Darstellung einer REST-basierten Interaktion zwischen Client und Server.

Die Struktur von RESTful-Ressourcen

Bei REST muss das Format für den Datenaustausch nicht angegeben werden, bevor eine Ressource über das Netzwerk gesendet wird. Solange eine REST API Daten in einem akzeptablen Format wie JSON, YAML oder XML ausgibt, können Entwickler eine API nach Belieben definieren.

Im Laufe der Jahre gab es den Trend, die Definition von REST-Ressourcen zu formalisieren. In der Specification First-Bewegung beispielsweise spezifiziert ein Entwickler zunächst die API über ein Spezifikationsformat wie OpenAPI oder API Blueprint. Anschließend erstellt der Entwickler die API auf Basis dieser Spezifikation. Dazu muss man sagen: Eine referenzierbare Spezifikation ist zwar gut, aber nicht unbedingt erforderlich.

Ein verantwortungsbewusster Entwickler veröffentlicht eine Dokumentation, in der jede Datenstruktur jeder Ressource in der API mit einem der vielen beliebten Dokumentations-Tools wie SwaggerHub beschrieben wird. (Meine Flughafencode-API auf SwaggerHub ist ein Beispiel dafür.) Manchmal publiziert ein Entwickler ein Dokument, das die API als Read.me-Datei in einem Quellcode-Repository wie GitHub beschreibt.

Und dann gibt es Zeiten, in denen ein Entwickler diese API überhaupt nicht dokumentiert – mit der Konsequenz, dass Sie es selbst herausfinden müssen. Ich halte dieses Vorgehen für verantwortungslos – aber eine solche Verantwortungslosigkeit kommt glücklicherweise selten vor. In diesen Fällen kann der Verbraucher zumindest die URL einer REST API auf einer Trial-and-Error-Basis abfragen, um nach verfügbaren Informationen zu suchen.

Ein Entwickler kann die API aufrufen, und das Ergebnis liegt in einem bekannten Textformat wie JSON oder XML vor. Eine besondere Dechiffrierung ist nicht erforderlich - es ist alles Text, die ganze Zeit.

Die Verwendung eines Textformats ist jedoch mit einem gewissen Aufwand verbunden. Das Senden und Empfangen von Text über ein Netzwerk kann kostspielig sein. Jedes Zeichen in einer Folge von Textzeichen ist ein Byte, so dass die folgende JSON-basierte Textzeichenfolge 62 Byte an Netzwerkdaten verbraucht:

{ "id": 501, "Spezies": "Hund", "Rasse": "Terrier", "Beine": 4 }

Wenn eine API eine einzelne Ressource veröffentlicht, ist das ist keine große Sache. Was aber passiert, wenn eine API Millionen von Ressourcen in einer Sammlung publiziert? Der Overhead kann beträchtlich werden. An dieser Stelle kommt gRPC zum Einsatz.

Die Funktionsweise von gRPC

gRPC wurde mit dem Ziel eingeführt, eine schnelle und effiziente Kommunikation zwischen einer Quelle und einem Ziel zu ermöglichen. Es basiert auf der RPC-Architektur, bei der eine Quelle eine vordefinierte Prozedur auf dem Ziel – in der Regel ein Endpunkt – aufruft.

Sowohl die Prozedur als auch die an eine Prozedur gesendeten Nachrichten werden in einer Spezifikationsdatei definiert. In gRPC hat die Spezifikationsdatei die Erweiterung .proto.

Der folgende Code zeigt ein Beispiel für die Spezifikationsdatei animal.proto. Das Listing definiert eine Methode, GetAnimal(), sowie zwei Nachrichten, AnimalRequest und Animal.

Beide Nachrichten werden in der Spezifikation für die Methode GetAnimal() verwendet. Ein Aufrufer, der die Methode GetAnimal() nutzt, liefert eine Animal-ID über die Nachricht AnimalRequest. Die Methode GetAnimal() gibt ein Tier entsprechend der ID im Format einer Animal-Nachricht zurück.

package animalpackage;

syntax = "proto3";

service AnimalCatalog {

// Sendet einen Gruß

rpc GetAnimal (AnimalRequest) returns (Animal) {}

}

// definiert eine Anfrage für ein Tier

message AnimalRequest {

int32 id = 1;

}

// definiert ein Tier

message Animal {

int32 id = 1;

string species = 2;

string breed = 3;

int32 legs = 4;

}

Die wesentliche Dynamik von gRPC besteht darin, dass eine Quelle eine Prozedur auf einem Ziel – mit einer vordefinierten Nachricht – aufruft und eine Antwort von dieser Prozedur erhält.

Die Serialisierung von Protokollpuffern unter gRPC verstehen

Neben einer vereinfachten Syntax für Methodenaufrufe ermöglicht gRPC auch eine verbesserte Leistung. Der Grund dafür ist, dass es den Datenaustausch effizienter macht. Die wichtigste Art und Weise, wie gRPC diese Vereinfachung handhabt, ist das binäre Serialisierungsformat für Protokollbuffer.

Client-Anwendungen, die gRPC unterstützen, kodieren Daten in Datenbytes gemäß der Codierungslogik für die Protokollbuffer. Diese codieren die Nachricht in ein binäres Format. Der Client sendet die Daten an Server, die wissen, dass Daten über Protokollbuffer ausgetauscht werden.

Nachdem der Server die Anfrage verarbeitet hat, kodiert er eine Antwort gemäß dem Serialisierungsformat von Protokollbuffern und sendet diese Bytes zurück an den Client. Der Client empfängt und entschlüsselt dann die Antwort des Servers.

Abbildung 3: Unter gRPC kodieren und dekodieren sowohl Client als auch Server Daten gemäß dem binären Format des Protocol Buffers.
Abbildung 3: Unter gRPC kodieren und dekodieren sowohl Client als auch Server Daten gemäß dem binären Format des Protocol Buffers.

Eine REST-animal-Ressource mit diesen Informationen wäre zum Beispiel 62 Byte groß und würde wie folgt aussehen:

{ id: 501, Spezies: Hund, Rasse: 'Terrier', Beine: 4}

Die gleiche JSON-Zeichenfolge, die mit Protokollbuffern kodiert wurde, ergibt ein Byte-Array, das die folgende Gestalt hat und nur neun Byte groß ist:

08 f5 03 12 03 44 6f 67 1a 07 54 65 72 72 69 65 72 20 04

Trotz des vereinfachten Formats und der geringeren Größe ist gRPC nicht für jede Situation geeignet.

REST und gRPC im Vergleich

REST als auch gRPC haben beide ihren Platz in der IT-Landschaft – mit jeweils spezifischen Vor- und Nachteilen.

In Bezug auf die Benutzerfreundlichkeit gewinnt REST haushoch. Wenn Entwickler eine REST API verwenden, entspricht dies im Wesentlichen dem Aufruf einer Webseite. Um eine REST API zu erstellen, benötigen Entwickler lediglich eine integrierte Entwicklungsumgebung, in der sie einen Webserver erstellen und starten. Um eine REST API zu nutzen, kann jeder Entwickler ein kostenloses Tool wie Postman oder cURL verwenden. Damit lassen sich HTTP-Aufrufe für einen Endpunkt konfigurieren und ausführen.

Der Nachteil von REST: REST ist sperrig und zustandslos. Eine REST-Antwort sendet eine Menge Daten über das Netzwerk, und das meiste davon hat mit der Datenstruktur zu tun und nicht mit den eigentlichen Daten selbst.

In REST können Entwickler keine Verbindung zu einem Ziel herstellen und dann dafür sorgen, dass das Ziel kontinuierlich Daten über diese Verbindung zurücksendet. Die Entwickler müssen in regelmäßigen Abständen die API aufrufen, um diese Daten zu erhalten.

gRPC auf der anderen Seite ist hingegen so konzipiert, dass es kontinuierliches Streaming unterstützt. Es verwendet das HTTP/2-Protokoll – und dieses Protokoll beinhaltet den integrierten Streaming-Support. Mit HTTP/2 können Entwickler eine Verbindung zu einem gRPC-fähigen Server herstellen. Diesen Server können sie dann veranlassen, kontinuierlich serialisierte Daten in Protokollbuffern an den Client zurückzusenden.

Der Nachteil von gRPC ist, dass Entwickler eine Menge Konzepte und Operationen kennen müssen, um es zu nutzen. Zum Beispiel müssen sowohl der Client als auch der Server die Spezifikation der .proto-Datei kennen. Beide verwenden diese Informationen, um die Kodierung und Dekodierung mit Protokollbuffern durchzuführen. Im Gegensatz zu REST können Entwickler einen Aufruf nicht ausführen, indem sie eine URL in ein Tool eingeben und ein Ergebnis in JSON zurückerhalten.

Sowohl auf dem Client als auch auf dem Server sind zahlreiche Kodierungs- und Dekodierungsvorgänge erforderlich, um mit der Serialisierung von Protokollbuffern zu arbeiten. Diese Kodierung und Dekodierung verbraucht Rechenressourcen, führt jedoch zu einem blitzschnellen Datenaustausch.

Sie müssen sich darüber im Klaren sein, dass Sie bei gRPC viel mehr Arbeit leisten müssen, um die Daten für die Nutzung sinnvoll aufzubereiten. Bei REST hingegen ist das, was Sie sehen, auch das, was Sie bekommen.

Die richtige Wahl treffen

Als REST vor mehr als zwei Jahrzehnten zum ersten Mal auftauchte, war es eine revolutionäre Architektur. Sie standardisierte den Datenaustausch und erleichterte es den Entwicklern, die benötigten Daten auf bekannte und zuverlässige Weise zu erhalten. Ohne REST wäre das, was als API-Economy bezeichnet wird, wahrscheinlich nicht möglich.

Dennoch hatte REST einen Nachteil für Entwickler von Microservices – vor allem für diejenigen, die sich nach Geschwindigkeit sehnen. Die große Masse der REST-Antworten kann eine Belastung für das Netzwerk darstellen. Wenn man genug Text in eine REST-Nachricht packt, kann es schnell langsam werden.

Für alle, denen Geschwindigkeit wichtig ist, gibt es gRPC. Der Nachteil von gRPC ist, dass man viel wissen muss, um es zu benutzen. Die IT-Abteilung muss abwägen, ob die Vorteile den Aufwand rechtfertigen, den gRPC erfordert.

Keine der beiden Architekturen kann für jeden alles sein. Die IT-Branche ist so groß und komplex, dass es keine einheitliche Technologie für den Datenaustausch gibt, die Geschwindigkeit und Benutzerfreundlichkeit vereint. Bis es so weit ist, sollten Sie sich mit den Grundlagen von REST UND gRPC vertraut machen. Dann finden Sie auch die passende Lösung für Ihr Unternehmen.

Erfahren Sie mehr über Softwareentwicklung