gRPC

gRPC ist ein modernes Open-Source-RPC (Remote Procedure Call)-Framework. Standardmäßig verwendet gRPC Protocol Buffers (Protobuf) als Interface Definition Language (IDL) zur Beschreibung sowohl des Interfaces als auch der Struktur der Payload Messages. In gRPC kann eine Clientanwendung direkt eine Methode auf einer entfernten Serveranwendung aufrufen als wäre es ein lokales Objekt, sodass verteilte Anwendungen und Dienste einfacher erstellt werden können. Wie in vielen RPC-Systemen basiert gRPC auf der Idee, einen Service zu definieren und die Methoden anzugeben, die mit ihren Parametern und Rückgabetypen aus der Ferne aufgerufen werden können. Der Server implementiert dieses Interface, um die Client-Aufrufe zu verarbeiten. Für den Client wurde ein sog. Stub generiert, der dieselben Methoden wie der Server bereitstellt.

Im folgenden die wesentlichen Design-Prinzipien von gRPC:

  • gRPC kann auf allen gängigen Entwicklungsplattformen und in vielen verschiedenen Sprachen erstellt werden.

  • Es ist auf Geräten mit geringer CPU- und Speicherfähigkeiten funktionsfähig sein, so neben Android [1]- und iOS-Geräten auch auf MicroPython-Boards und in Browsern [2] [3].

  • Es ist lizenziert unter Apache License 2.0 und nutzt offene Standards wie z.B. HTTP/2 und Quick UDP Internet Connections (QUIC).

  • gRPC ist interoperabel und kann daher z.B. auch im LoRaWan (Long Range Wide Area Network) genutzt werden.

  • Die einzelnen Layer können unabhängig voneinander entwickelt werden. So kann z.B. der Transport-Layer (OSI-Layer 4) unabhängig vom Application-Layer (OSI-Layer 7) entwickelt werden.

  • gRPC unterstützt unterschiedliche Serialisierungsformate, u.a. Protocol Buffers (Protobuf), JSON [4], XML/HTML und Thrift)

  • Asynchrone und synchrone (blockierende) Verarbeitung werden in den meisten Sprachen unterstützt.

  • Das Streaming von Nachrichten in einem einzelnen RPC-Aufruf wird unterstützt.

  • gRPC erlaubt Protokollerweiterungen für Sicherheit, Integritätsprüfung, Lastausgleich, Failover etc.

digraph grpc_concept { rankdir="LR"; graph [fontname = "Calibri", fontsize="16", penwidth="5px", overlap=false]; node [fontname = "Calibri", fontsize="16", style="bold", penwidth="5px"]; edge [fontname = "Calibri", fontsize="16", style="bold", penwidth="5px"]; tooltip="gRPC concept"; // C++ service subgraph "cluster_cpp_service" { label="C++ Service"; fontcolor="#2D7BFD"; shape=box; style= "rounded"; color="#2D7BFD"; "grpc_server" [ label="gRPC server", fontcolor="#640FFB" shape=box, style= "rounded", color="#640FFB" ]; } // Python-Stub subgraph cluster_python_client { label="Python client"; fontcolor="#2D7BFD"; shape=box; style= "rounded"; color="#2D7BFD"; grpc_python_stub [ label="gRPC Python-Stub", fontcolor="#640FFB" shape=box, style= "rounded", color="#640FFB" ]; } // Android-Java-Stub subgraph cluster_android_java_client { label="Android-Java client"; fontcolor="#2D7BFD"; shape=box; style= "rounded"; color="#2D7BFD"; grpc_android_java_stub [ label="gRPC Android-Java-Stub", fontcolor="#640FFB" shape=box, style= "rounded", color="#640FFB" ]; } grpc_python_stub -> grpc_server [label="Proto-Request", fontcolor="#640FFB", color="#7539FC"] grpc_android_java_stub -> grpc_server [label="Proto-Request", fontcolor="#640FFB", color="#7539FC"] grpc_server -> grpc_python_stub [label="Proto-Response", fontcolor="#300099", color="#300099"] grpc_server -> grpc_android_java_stub [label="Proto-Response", fontcolor="#300099", color="#300099"] }

Ausgehend von einer Schnittstellendefinition in einer .proto-Datei bietet gRPC Protocol-Compiler-Plugins, die clientseitige und serverseitige APIs generieren. Das gRPC-Protokoll gibt abstrakt die Kommunikation zwischen Clients und Servern an:

  1. Zuerst wird der Stream vom Client mit einem obligatorischen Call Header gestartet

    1. gefolgt von optionalen Initial-Metadata

    2. gefolgt von optionalen Payload Messages.

    Die Inhalte von Call Header und Initial Metadata werden als HTTP/2-Headers mit HPACK komprimiert.

  2. Der Server antwortet mit optionalen Initial-Metadata

    1. gefolgt von Payload Messages

    2. und schließlich mit obligatorischem Status und optionalen Status-Metadata.

    Payload-Nachrichten werden in einen Byte-Stream serialisiert, der in HTTP/2-Frames fragmentiert ist. Status und Trailing-Metadata werden als HTTP/2-Trailing-Headers gesendet.

Im Gegensatz zu FastAPI kann die gRPC-API jedoch nicht einfach auf der Kommandozeile mit cURL getestet werden. Ggf. könnt ihr jedoch grpcurl verwenden. Dies setzt jedoch voraus, dass der gRPC-Server das GRPC Server Reflection Protocol unterstützt. Üblicherweise sollte Reflection jedoch nur in der Entwicklungsphase zur Verfügung stehen. Dann könnt ihr jedoch grpcurl aufrufen, z.B. mit:

$ grpcurl localhost:9111 list

Siehe auch