wann welches Protokoll für interne Services
GraphQL und gRPC lösen unterschiedliche Probleme, auch wenn beide oft in derselben Architektur nebeneinander stehen. GraphQL glänzt bei flexiblen, client-gesteuerten Abfragen für Frontends, gRPC bei binärer, latenzarmer Kommunikation zwischen Backend-Services. Dieser Artikel zeigt, wann welches Protokoll die bessere Wahl ist.
Inhaltsverzeichnis
- 1. Zwei Protokolle, zwei unterschiedliche Einsatzzwecke
- 2. gRPC-Grundlagen: Protobuf, HTTP/2, Streaming
- 3. GraphQL im Kontext interner Service-Kommunikation
- 4. Performance-Vergleich: Serialisierung und Payload-Größe
- 5. Typsicherheit und Codegen: .proto vs. SDL
- 6. Typische Use-Cases: wann gRPC, wann GraphQL
- 7. Das BFF-Pattern: GraphQL vorne, gRPC dahinter
- 8. Magento und interne Services in der Praxis
- 9. GraphQL und gRPC im direkten Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Zwei Protokolle, zwei unterschiedliche Einsatzzwecke
GraphQL und gRPC werden oft als konkurrierende Technologien dargestellt, dabei lösen sie in der Praxis meist unterschiedliche Probleme innerhalb derselben Systemlandschaft. GraphQL wurde entwickelt, um Frontend-Clients eine flexible, selbstbestimmte Abfrage von Daten über eine einzige Schnittstelle zu ermöglichen, mit dem Ziel, Over-Fetching und Under-Fetching zu vermeiden. gRPC wurde von Google entwickelt, um latenzarme, typsichere Kommunikation zwischen Backend-Services in derselben Infrastruktur zu ermöglichen, mit Fokus auf Performance statt auf Client-Flexibilität.
Der Unterschied zeigt sich schon am Transportformat: GraphQL läuft praktisch immer über HTTP mit JSON-Payloads, textbasiert und dadurch leicht zu debuggen, aber mit spürbarem Serialisierungs-Overhead. gRPC nutzt Protocol Buffers, ein binäres Serialisierungsformat, über HTTP/2, was deutlich kompaktere Nachrichten und geringere Latenz ermöglicht, dafür aber ohne spezielle Tools nicht direkt im Browser lesbar ist. Diese fundamentalen Unterschiede bestimmen, für welchen Einsatzzweck welches Protokoll die bessere Wahl ist.
2. gRPC-Grundlagen: Protobuf, HTTP/2, Streaming
Das Fundament von gRPC ist die Protocol-Buffer-Definitionssprache, kurz Protobuf, in der Services und Nachrichtenstrukturen in einer .proto-Datei deklariert werden. Aus dieser einen Datei generiert der Protobuf-Compiler Client- und Server-Code für praktisch jede verbreitete Sprache, Go, Java, PHP, TypeScript und viele weitere, mit vollständiger Typsicherheit auf beiden Seiten der Verbindung. Diese Codegen-first-Philosophie unterscheidet sich fundamental vom eher dokumentbasierten Ansatz vieler GraphQL-Setups.
Ein entscheidender Vorteil von gRPC gegenüber klassischem REST und auch gegenüber Standard-GraphQL ist natives Streaming über HTTP/2: Server-Streaming, Client-Streaming und bidirektionales Streaming sind fester Bestandteil der Spezifikation, nicht nachträglich aufgesetzt. Ein Service, der kontinuierlich Lagerbestandsänderungen an einen Backend-Consumer sendet, kann das über eine einzige, langlebige gRPC-Verbindung tun, ohne Polling oder eine separate WebSocket-Infrastruktur aufzubauen. Diese Eigenschaft macht gRPC besonders attraktiv für Service-zu-Service-Kommunikation mit hohem Datendurchsatz.
// inventory.proto — service definition, generates typed clients for every language
syntax = "proto3";
package inventory.v1;
service InventoryService {
// Unary call — one request, one response
rpc GetStock(GetStockRequest) returns (StockResponse);
// Server streaming — one request, continuous stream of updates
rpc WatchStockChanges(WatchRequest) returns (stream StockChangeEvent);
}
message GetStockRequest {
string sku = 1;
}
message StockResponse {
string sku = 1;
int32 quantity = 2;
bool in_stock = 3;
}
message WatchRequest {
repeated string skus = 1;
}
message StockChangeEvent {
string sku = 1;
int32 new_quantity = 2;
int64 changed_at = 3;
}
3. GraphQL im Kontext interner Service-Kommunikation
Während gRPC für Service-zu-Service-Kommunikation entwickelt wurde, ist GraphQL in erster Linie eine Client-facing-Technologie, die Frontends eine flexible Abfragesprache über eine stabile, öffentliche Schnittstelle bietet. Ein GraphQL-Server aggregiert dabei häufig Daten aus mehreren internen Quellen, darunter durchaus auch gRPC-Services, und präsentiert sie als ein einheitliches, für Clients verständliches Schema. GraphQL ist also selten die Lösung für die interne Service-zu-Service-Kommunikation selbst, sondern die Schnittstelle, die diese internen Services nach außen bündelt.
Ein wichtiger Unterschied: GraphQL-Requests sind dynamisch, ein Client entscheidet zur Laufzeit, welche Felder er abfragt, während gRPC-Aufrufe statisch über die .proto-Datei definiert sind, mit einer festen Menge an Feldern pro Nachricht. Diese Dynamik ist bei nutzergesteuerten Frontend-Abfragen ein Vorteil, wird aber bei interner Service-Kommunikation, wo beide Seiten ohnehin kontrolliert deployt werden, selten gebraucht und kostet dort nur zusätzlichen Parsing- und Validierungsaufwand pro Request.
4. Performance-Vergleich: Serialisierung und Payload-Größe
Der Performance-Unterschied zwischen GraphQL und gRPC liegt hauptsächlich im Serialisierungsformat. JSON, wie es GraphQL standardmäßig nutzt, ist textbasiert, menschenlesbar und dadurch größer als nötig, weil Feldnamen bei jeder einzelnen Nachricht wiederholt als String übertragen werden. Protobuf hingegen kodiert Feldnamen als Nummern gemäß der .proto-Definition, wodurch Nachrichten in Benchmarks häufig 60 bis 80 Prozent kleiner ausfallen als das äquivalente JSON, bei gleichzeitig schnellerer Serialisierung und Deserialisierung durch beide Kommunikationspartner.
Für ein einzelnes Frontend-Request-Response-Paar mag dieser Unterschied vernachlässigbar sein. Bei interner Service-Kommunikation mit tausenden Aufrufen pro Sekunde zwischen Microservices summiert sich der Overhead von JSON-Serialisierung jedoch spürbar auf, sowohl in CPU-Zeit als auch in Netzwerkbandbreite. Das ist der Hauptgrund, warum gRPC in latenzsensiblen internen Pfaden, etwa zwischen einem Order-Service und einem Payment-Service, häufig die bessere Wahl ist, während GraphQL an der Außengrenze zum Frontend seine Flexibilität ausspielt.
5. Typsicherheit und Codegen: .proto vs. SDL
Beide Protokolle bieten starke Typsicherheit, aber mit unterschiedlichen Schwerpunkten. Die .proto-Datei bei gRPC ist von Natur aus streng typisiert, jede Nachricht hat feste Felder mit festen Typen, und der generierte Code macht Abweichungen zur Compile-Zeit sichtbar, in praktisch jeder unterstützten Sprache identisch. Diese Konsistenz über Sprachgrenzen hinweg ist einer der größten praktischen Vorteile von gRPC in polyglotten Microservice-Landschaften mit Go-, Java- und PHP-Services im selben System.
Bei GraphQL entsteht Typsicherheit über die SDL-Datei kombiniert mit Codegen-Tools wie GraphQL Code Generator, die daraus TypeScript-Interfaces oder PHP-Stubs erzeugen. Der Unterschied: GraphQL erlaubt Nullability granular pro Feld und unterstützt Interfaces und Unions für polymorphe Typen direkt im Schema, was Protobuf in dieser Ausdrucksform nicht kennt, dort wird Polymorphie meist über oneof-Felder oder separate Nachrichtentypen nachgebildet. Für Frontend-nahe Datenmodellierung mit vielen optionalen und alternativen Feldern ist die GraphQL-Typsprache oft ausdrucksstärker.
// inventory-client.ts — generated gRPC client, fully typed from the .proto file
import { InventoryServiceClient } from './generated/inventory_grpc_pb';
import { GetStockRequest } from './generated/inventory_pb';
import { credentials } from '@grpc/grpc-js';
const client = new InventoryServiceClient(
'inventory-service:50051',
credentials.createInsecure()
);
function getStock(sku: string): Promise<{ quantity: number; inStock: boolean }> {
return new Promise((resolve, reject) => {
const request = new GetStockRequest();
request.setSku(sku);
// Typed response — compiler catches any field mismatch at build time
client.getStock(request, (err, response) => {
if (err) return reject(err);
resolve({
quantity: response.getQuantity(),
inStock: response.getInStock(),
});
});
});
}
#!/usr/bin/env bash
# debug-grpc.sh — grpcurl lets you inspect and call a gRPC service like curl for REST
set -euo pipefail
# List all services exposed by the running gRPC server (requires reflection enabled)
grpcurl -plaintext inventory-service:50051 list
# Describe a specific service, showing its methods and message types
grpcurl -plaintext inventory-service:50051 describe inventory.v1.InventoryService
# Call the unary GetStock method with a JSON-encoded request payload
grpcurl -plaintext -d '{"sku": "TEST-001"}' \
inventory-service:50051 inventory.v1.InventoryService/GetStock
6. Typische Use-Cases: wann gRPC, wann GraphQL
gRPC spielt seine Stärken aus, wenn beide Kommunikationspartner unter eigener Kontrolle stehen, die Latenz kritisch ist und hoher Durchsatz erwartet wird: Kommunikation zwischen internen Microservices, Streaming von Sensordaten oder Ereignissen, sowie Server-zu-Server-Aufrufe in einer Kubernetes-Umgebung mit Service-Mesh. Auch bei mobilen Apps mit eingeschränkter Bandbreite kann gRPC-Web als kompaktere Alternative zu JSON-basierten APIs sinnvoll sein, allerdings mit zusätzlichem Infrastruktur-Aufwand für den gRPC-Web-Proxy.
GraphQL ist die bessere Wahl, wenn unterschiedliche, nicht kontrollierte Frontend-Clients dieselbe API konsumieren, die genauen Datenanforderungen sich häufig ändern, oder mehrere heterogene Backend-Quellen für ein Frontend in einer einzigen Antwort zusammengeführt werden müssen. Ein E-Commerce-Storefront, der Produktdaten, Bewertungen und Lagerbestand in einer einzigen Query abfragt, profitiert von GraphQLs Fähigkeit, genau die benötigten Felder zusammenzustellen, unabhängig davon, aus wie vielen internen Quellen diese stammen.
7. Das BFF-Pattern: GraphQL vorne, gRPC dahinter
In der Praxis schließen sich GraphQL und gRPC nicht aus, sondern ergänzen sich in einem verbreiteten Architekturmuster: Ein GraphQL-Server fungiert als Backend-for-Frontend und ruft im Hintergrund mehrere interne gRPC-Services auf, um die Antwort auf eine einzelne GraphQL-Query zusammenzustellen. Das Frontend sieht nur die flexible, gut dokumentierte GraphQL-Schnittstelle, während die interne Kommunikation zwischen dem BFF und den Backend-Services von gRPCs Performance-Vorteilen profitiert.
Dieses kombinierte Muster erfordert sorgfältiges Resolver-Design: Ein GraphQL-Resolver, der einen gRPC-Aufruf kapselt, sollte gRPC-spezifische Fehlercodes in GraphQL-Fehler mit passenden extensions übersetzen, statt die interne Protokoll-Details an den Client durchzureichen. DataLoader-Patterns helfen zusätzlich, mehrere gRPC-Aufrufe für verschiedene Felder derselben Query zu batchen, statt für jedes Feld einen eigenen Netzwerk-Roundtrip zum internen Service zu erzeugen.
// product-resolver.ts — GraphQL resolver wraps an internal gRPC call (BFF pattern)
import { getStock } from './inventory-client';
const resolvers = {
Product: {
async stock(product: { sku: string }) {
try {
// Internal gRPC call — fast, binary, not exposed to the GraphQL client
const { quantity, inStock } = await getStock(product.sku);
return { quantity, inStock };
} catch (err) {
// Translate gRPC error into a GraphQL-shaped error, never leak proto details
throw new GraphQLError('Stock information temporarily unavailable', {
extensions: { code: 'INVENTORY_SERVICE_UNAVAILABLE' },
});
}
},
},
};
# Client-facing query — the client never knows a gRPC call happens behind "stock"
query ProductDetail {
product(sku: "TEST-001") {
name
price
# Resolved via an internal gRPC call to InventoryService.GetStock
stock {
quantity
inStock
}
}
}
8. Magento und interne Services in der Praxis
Magentos eigener GraphQL-Endpunkt ist konsequent eine Frontend-facing-Schnittstelle und spricht standardmäßig kein gRPC, weil das PHP-Ökosystem und die historische Magento-Architektur nicht darauf ausgelegt sind. In größeren Magento-Landschaften mit separaten, in Go oder Java geschriebenen Microservices, etwa für Preisberechnung, Verfügbarkeitsprüfung oder Empfehlungen, ist es aber ein bewährtes Muster, dass ein Magento-GraphQL-Resolver intern per gRPC mit diesen Services kommuniziert, statt sie über langsameres HTTP/JSON anzusprechen.
PHP unterstützt gRPC über die offizielle grpc/grpc-Extension und generierten Protobuf-Code, was in der Praxis etwas mehr Infrastruktur-Aufwand bedeutet als eine einfache HTTP-Anfrage mit Guzzle. Für Magento-Projekte mit wenigen internen Services lohnt sich dieser Aufwand oft erst ab einer gewissen Skalierung, während kleinere Setups gut mit klassischem REST oder sogar internem GraphQL zwischen Services auskommen, solange Latenz und Durchsatz keine kritischen Engpässe darstellen.
9. GraphQL und gRPC im direkten Vergleich
Die folgende Tabelle stellt die wichtigsten Eigenschaften beider Protokolle gegenüber.
| Kriterium | GraphQL | gRPC |
|---|---|---|
| Serialisierung | JSON, textbasiert, lesbar | Protobuf, binär, kompakt |
| Streaming | Nur via Subscriptions, meist zusätzliches Setup | Nativ, bidirektional, Teil der Spezifikation |
| Client-Flexibilität | Client wählt Felder zur Laufzeit | Feste Nachrichtenstruktur aus .proto |
| Browser-Support | Direkt nutzbar | Nur über gRPC-Web mit Proxy |
| Typischer Einsatz | Frontend-facing API, BFF | Interne Service-zu-Service-Kommunikation |
Die Tabelle macht deutlich: GraphQL und gRPC konkurrieren selten in derselben Rolle. GraphQL gewinnt bei Flexibilität und direkter Browser-Nutzbarkeit, gRPC bei Performance und nativem Streaming für interne Service-Landschaften.
Mironsoft
API-Architektur, Microservices und Protokollstrategie
Das richtige Protokoll für eure Service-Landschaft finden?
Wir analysieren eure interne und externe API-Kommunikation und empfehlen, wo GraphQL, wo gRPC und wo eine Kombination aus beidem im BFF-Pattern die beste Lösung ist.
Protokoll-Audit
Bestehende Service-Kommunikation auf Performance-Engpässe analysieren
gRPC-Integration
Protobuf-Schemas und PHP-Anbindung für interne Services aufbauen
BFF-Architektur
GraphQL-Layer vor bestehenden gRPC- und REST-Services etablieren
10. Zusammenfassung
GraphQL und gRPC sind keine austauschbaren Alternativen, sondern Protokolle für unterschiedliche Rollen in derselben Architektur. GraphQL bietet Frontend-Clients flexible, selbstbestimmte Abfragen über eine gut dokumentierte, direkt im Browser nutzbare Schnittstelle. gRPC bietet interner Service-zu-Service-Kommunikation binäre Effizienz, native Typsicherheit über Sprachgrenzen hinweg und eingebautes Streaming, das GraphQL ohne Zusatzaufwand nicht bietet.
Das BFF-Pattern, bei dem ein GraphQL-Server als Fassade vor internen gRPC-Services steht, vereint die Stärken beider Protokolle: Performance dort, wo sie zählt, im internen Datenpfad, und Flexibilität dort, wo Clients sie brauchen, an der Außengrenze zum Frontend. Für Magento-Projekte mit wachsender Microservice-Landschaft lohnt sich diese Kombination meist erst ab einer gewissen Größe, während kleinere Setups gut mit einfacheren Protokollen auskommen.
GraphQL vs. gRPC für interne Services — Das Wichtigste auf einen Blick
GraphQL
JSON über HTTP, flexible Client-Queries, ideal als Frontend-facing API und BFF-Layer.
gRPC
Protobuf über HTTP/2, kompakt, natives Streaming, ideal für interne Service-Kommunikation.
BFF-Pattern
GraphQL als Fassade vor internen gRPC-Services kombiniert Flexibilität und Performance.
Entscheidungskriterium
Kontrolle über beide Endpunkte und Latenzanforderung entscheiden, nicht persönliche Vorliebe.