GraphQL und gRPC: welches Protokoll für interne Services?
AI generated
{ }
type
GraphQL · gRPC · Microservices · Protobuf
GraphQL und gRPC
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.

18 Min. Lesezeit Protobuf · HTTP/2 · Streaming · BFF-Pattern GraphQL · gRPC · Architektur

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.

11. FAQ: GraphQL und gRPC für interne Services

1Direkte Konkurrenten?
Selten. GraphQL ist Frontend-facing, gRPC für interne Service-Kommunikation. Oft im selben System kombiniert.
2Warum ist gRPC performanter?
Protobuf kodiert Feldnamen als Nummern statt Strings, Nachrichten oft 60 bis 80 Prozent kleiner als äquivalentes JSON.
3Kann GraphQL streamen?
Nur über Subscriptions mit Zusatzinfrastruktur. gRPC hat Streaming fest in der Spezifikation.
4gRPC im Browser?
Nicht direkt. Ein gRPC-Web-Proxy übersetzt zwischen Browser-Format und echtem gRPC.
5Was ist das BFF-Pattern?
GraphQL-Server als Fassade, der intern gRPC-Services aufruft und die Antwort zusammenstellt.
6gRPC-Fehler in GraphQL übersetzen?
Im Resolver abfangen und in GraphQLError mit passenden extensions umwandeln, keine internen Details durchreichen.
7Unterstützt PHP gRPC?
Ja, über die grpc/grpc-Extension und generierten Protobuf-Code, mit etwas mehr Infrastruktur-Aufwand.
8Wann gRPC bei Magento?
Ab mehreren internen Microservices, wenn Latenz und Durchsatz zwischen diesen zum kritischen Faktor werden.
9.proto vs. GraphQL-SDL?
Konzeptionell ähnlich. .proto strenger typisiert, SDL erlaubt granularere Nullability und native Unions.
10Protokoll für mobile Apps?
gRPC-Web mit kompakteren Payloads möglich, aber Proxy nötig. GraphQL bleibt meist die praktikablere Wahl.