gRPC JSON-Transcodierung in ASP.NET Core

Von James Newton-King

gRPC ist ein Remoteprozeduraufruf (RPC) mit hoher Leistung. gRPC erstellt leistungsstarke Echtzeitdienste mithilfe von HTTP/2, Streaming, Protobuf und Nachrichtenverträgen.

Eine Einschränkung von gRPC ist jedoch, dass es nicht von jeder Plattform genutzt werden kann. Browser unterstützen HTTP/2 nicht vollständig, sodass RESTAPIs und JSON die primären Methoden sind, um Daten in Browser-Apps zu übertragen. Trotz der Vorteile von gRPC sind REST APIs und JSON ein wichtiger Bestandteil moderner Apps. Wenn Sie gRPC undJSJSON-Web-APIs entwickeln, steigt der Aufwand für die App-Entwicklung.

In diesem Dokument wird erläutert, wie JSON-Web-APIs mithilfe von gRPC-Diensten erstellt werden.

Übersicht

gRPC JSON-Transcodierung ist eine Erweiterung für ASP.NET Core, mit der RESTful-JSON-APIs für gRPC-Dienste erstellt werden. Einmal konfiguriert, ermöglicht die Transcodierung Apps den Aufruf von gRPC-Diensten mit den bekannten HTTP-Konzepten:

  • HTTP-Verben
  • URL-Parameterbindung
  • JSON-Anforderungen und -Antworten

gRPC kann weiterhin zum Aufrufen von Diensten verwendet werden.

Hinweis

gRPC JSON Transcodierung ersetzt gRPC HTTP API, eine alternative experimentelle Erweiterung.

Verwendung

  1. Fügen Sie Microsoft.AspNetCore.Grpc.JsonTranscoding einen Paketverweis hinzu.

  2. Registrieren Sie die Transcodierung im Serverstartcode, indem Sie AddJsonTranscoding hinzufügen: Ändern Sie in der Program.cs-Datei builder.Services.AddGrpc(); in builder.Services.AddGrpc().AddJsonTranscoding();.

  3. Fügen Sie <IncludeHttpRuleProtos>true</IncludeHttpRuleProtos> zur Eigenschaftengruppe in der Projektdatei (.csproj) hinzu:

    <Project Sdk="Microsoft.NET.Sdk.Web">
    
      <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <Nullable>enable</Nullable>
        <ImplicitUsings>enable</ImplicitUsings>
        <InvariantGlobalization>true</InvariantGlobalization>
        <IncludeHttpRuleProtos>true</IncludeHttpRuleProtos>
      </PropertyGroup>
    
  4. Kommentieren Sie die gRPC-Methoden in Ihren .proto-Dateien mit HTTP-Bindungen und -Routen:

    syntax = "proto3";
    
    option csharp_namespace = "GrpcServiceTranscoding";
    import "google/api/annotations.proto";
    
    package greet;
    
    // The greeting service definition.
    service Greeter {
      rpc SayHello (HelloRequest) returns (HelloReply) {
        option (google.api.http) = {
          get: "/v1/greeter/{name}"
        };
      }
    }
    
    // The request message containing the user's name.
    message HelloRequest {
      string name = 1;
    }
    
    // The response message containing the greetings.
    message HelloReply {
      string message = 1;
    }
    

Die gRPC-Methode SayHello kann jetzt als gRPC, Protobuf und als eine JSON Web-API aufgerufen werden:

  • Anforderung: GET /v1/greeter/world
  • Antwort: { "message": "Hello world" }

Wenn der Server so konfiguriert ist, dass jede Anforderung protokolliert wird, zeigen die Serverprotokolle, dass der HTTP-Aufruf von einem gRPC-Dienst ausgeführt wird. Die Transcodierung ordnet die eingehende HTTP-Anforderung einer gRPC-Nachricht zu und konvertiert die Antwortnachricht in JSON.

info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/1.1 GET https://localhost:5001/v1/greeter/world
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint 'gRPC - /v1/greeter/{name}'
info: Server.GreeterService[0]
      Sending hello to world
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint 'gRPC - /v1/greeter/{name}'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished in 1.996ms 200 application/json

Hinzufügen von Anmerkungen zu gRPC-Methoden

gRPC-Methoden müssen mit einer HTTP-Regel versehen werden, damit sie die Transcodierung unterstützen. Die HTTP-Regel enthält Informationen darüber, wie die gRPC-Methode aufgerufen werden muss, z. B. als HTTP-Methode und Route.

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {
    option (google.api.http) = {
      get: "/v1/greeter/{name}"
    };
  }
}

Beispiel für die Vorgehensweise:

  • Definiert einen Greeter-Dienst mit einer SayHello-Methode. Die Methode verfügt über eine HTTP-Regel, die mithilfe des Namens google.api.httpangegeben wird.
  • Auf die Methode kann mit GET-Anforderungen und der /v1/greeter/{name}-Route zugegriffen werden.
  • Das name-Feld in der Anforderungsnachricht ist an einen Routenparameter gebunden.

Es stehen viele Optionen zum Anpassen der Bindung einer gRPC-Methode an eine RESTful-API zur Verfügung. Weitere Informationen zum Versehen von gRPC-Methoden mit Anmerkungen und zum Anpassen von JSON finden Sie unter Konfigurieren von HTTP und JSON für gRPC JSON-Transcodierung.

Streamingmethoden

Herkömmliches gRPC über HTTP/2 unterstützt das Streamen in alle Richtungen. Die Transcodierung ist nur auf Serverstreaming beschränkt. Client- und bidirektionale Streamingmethoden werden nicht unterstützt.

Serverstreamingmethoden verwenden durch Zeilen getrenntes JSON. Jede mit WriteAsync geschriebene Nachricht wird in JSON serialisiert und von einer neuen Zeile begleitet.

Die folgende Serverstreamingmethode schreibt drei Nachrichten:

public override async Task StreamingFromServer(ExampleRequest request,
    IServerStreamWriter<ExampleResponse> responseStream, ServerCallContext context)
{
    for (var i = 1; i <= 3; i++)
    {
        await responseStream.WriteAsync(new ExampleResponse { Text = $"Message {i}" });
        await Task.Delay(TimeSpan.FromSeconds(1));
    }
}

Der Client empfängt drei durch Zeilen getrennte JSON-Objekte:

{"Text":"Message 1"}
{"Text":"Message 2"}
{"Text":"Message 3"}

Beachten Sie, dass die WriteIndentedJSON-Einstellung nicht für Serverstreamingmethoden gilt. Die automatische Strukturierung und Einrückung fügt neue Zeilen und Leerzeichen zu JSON hinzu, die nicht mit durch Zeilen getrenntes JSON verwendet werden können.

Zeigen Sie ein Beispiel für eine ASP.NET Core gPRC-Transcodierungs- und Streaming-App an, oder laden Sie es herunter.

HTTP-Protokoll

Die im . NET SDK enthaltene ASP.NET Core gRPC-Dienstvorlage erstellt eine App, die nur für HTTP/2 konfiguriert ist. HTTP/2 ist eine geeignete Standardeinstellung, wenn eine App nur herkömmliches gRPC über HTTP/2 unterstützt. Die Transcodierung funktioniert jedoch sowohl mit HTTP/1.1 als auch mit HTTP/2. Einige Plattformen, z. B. UWP oder Unity, können HTTP/2 nicht verwenden. Um alle Client-Apps zu unterstützen, konfigurieren Sie den Server so, dass HTTP/1.1 und HTTP/2 aktiviert sind.

Ändern Sie das Standardprotokoll in appsettings.json:

{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1AndHttp2"
    }
  }
}

Alternativ können Sie Kestrel-Endpunkte im Startcode konfigurieren.

Das Aktivieren von HTTP/1.1 und HTTP/2 für denselben Port erfordert TLS für die Protokollaushandlung. Weitere Informationen zum Konfigurieren von HTTP-Protokollen in einer gRPC-App finden Sie unter ASP.NET Core gRPC-Protokollaushandlung.

gRPC JSON-Transcodierung im Vergleich zu gRPC-Web

Die Transcodierung und gRPC-Web ermöglichen es, gRPC-Dienste in einem Browser aufzurufen. Die Vorgehensweise unterscheidet sich jedoch:

  • Mit gRPC-Web können Browser-Apps gRPC-Dienste mithilfe des gRPC-Web-Client und Protobuf über den Browser aufrufen. gRPC-Web erfordert, dass die Browser-App einen gRPC-Client generiert, und hat den Vorteil, dass kleine, schnelle Protobuf-Nachrichten gesendet werden.
  • Die Transcodierung ermöglicht es Browser-Apps, gRPC-Dienste so aufzurufen, als wären sie RESTful-APIs mit JSON. Die Browser-App muss keinen gRPC-Client generieren und benötigt keine Informationen zu gRPC.

Der vorherige Greeter-Dienst kann mithilfe von JavaScript-APIs für den Browser aufgerufen werden:

var name = nameInput.value;

fetch('/v1/greeter/' + name)
  .then((response) => response.json())
  .then((result) => {
    console.log(result.message);
    // Hello world
  });

grpc-gateway

gRPC-Gateway ist eine weitere Technologie, um RESTful-JSON-APIs aus gRPC-Diensten zu erstellen. Es werden die gleichen .proto-Anmerkungen verwendet, um HTTP-Konzepte gRPC-Diensten zuzuordnen.

grpc-gateway verwendet Code-Generierung, um einen Reverse-Proxyserver zu erstellen. Der Reverseproxy übersetzt RESTful-Aufrufe in gRPC+Protobuf und sendet die Aufrufe über HTTP/2 an den gRPC-Dienst. Der Nutzen dieses Ansatzes ist, dass der gRPC-Dienst die RESTful JSON-APIs nicht kennt. Jeder gRPC-Server kann grpc-gateway verwenden.

Währenddessen wird die gRPC JSON-Transcodierung in einer ASP.NET Core-App ausgeführt. Es deserialisiert JSON in Protobuf-Nachrichten und ruft dann den gRPC-Dienst direkt auf. Die Transcodierung in ASP.NET Core bietet Vorteile für Entwickler von .NET-Apps:

  • Weniger komplex: Sowohl gRPC-Dienste als auch zugeordnete RESTful JSON-API laufen aus einer ASP.NET Core-App heraus.
  • Bessere Leistung: Die Transcodierung deserialisiert JSON in Protobuf-Nachrichten und ruft den gRPC-Dienst direkt auf. Es gibt erhebliche Leistungsvorteile bei dieser In-Process-Ausführung und zum Erstellen eines neuen gRPC-Aufrufs an einen anderen Server.
  • Geringere Kosten: Weniger Server führen zu einer kleineren monatlichen Hostingrechnung.

Weitere Informationen zur Installation und Verwendung von grpc-gateway finden Sie in der INFODATEI zu grpc-gateway.

Zusätzliche Ressourcen

gRPC ist ein Remoteprozeduraufruf (RPC) mit hoher Leistung. gRPC erstellt leistungsstarke Echtzeitdienste mithilfe von HTTP/2, Streaming, Protobuf und Nachrichtenverträgen.

Eine Einschränkung von gRPC ist jedoch, dass es nicht von jeder Plattform genutzt werden kann. Browser unterstützen HTTP/2 nicht vollständig, sodass RESTAPIs und JSON die primären Methoden sind, um Daten in Browser-Apps zu übertragen. Trotz der Vorteile von gRPC sind REST APIs und JSON ein wichtiger Bestandteil moderner Apps. Wenn Sie gRPC undJSJSON-Web-APIs entwickeln, steigt der Aufwand für die App-Entwicklung.

In diesem Dokument wird erläutert, wie JSON-Web-APIs mithilfe von gRPC-Diensten erstellt werden.

Übersicht

gRPC JSON-Transcodierung ist eine Erweiterung für ASP.NET Core, mit der RESTful-JSON-APIs für gRPC-Dienste erstellt werden. Einmal konfiguriert, ermöglicht die Transcodierung Apps den Aufruf von gRPC-Diensten mit den bekannten HTTP-Konzepten:

  • HTTP-Verben
  • URL-Parameterbindung
  • JSON-Anforderungen und -Antworten

gRPC kann weiterhin zum Aufrufen von Diensten verwendet werden.

Hinweis

gRPC JSON Transcodierung ersetzt gRPC HTTP API, eine alternative experimentelle Erweiterung.

Verwendung

  1. Fügen Sie Microsoft.AspNetCore.Grpc.JsonTranscoding einen Paketverweis hinzu.
  2. Registrieren Sie die Transcodierung im Serverstartcode, indem Sie AddJsonTranscoding hinzufügen: Ändern Sie in der Program.cs-Datei builder.Services.AddGrpc(); in builder.Services.AddGrpc().AddJsonTranscoding();.
  3. Erstellen Sie die Verzeichnisstruktur /google/api im Projektverzeichnis, das die .csproj-Datei enthält.
  4. Fügen Sie die Dateien google/api/http.proto und google/api/annotations.proto dem Verzeichnis /google/api hinzu.
  5. Kommentieren Sie die gRPC-Methoden in Ihren .proto-Dateien mit HTTP-Bindungen und -Routen:
syntax = "proto3";

option csharp_namespace = "GrpcServiceTranscoding";
import "google/api/annotations.proto";

package greet;

// The greeting service definition.
service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {
    option (google.api.http) = {
      get: "/v1/greeter/{name}"
    };
  }
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings.
message HelloReply {
  string message = 1;
}

Die gRPC-Methode SayHello kann jetzt als gRPC, Protobuf und als eine JSON Web-API aufgerufen werden:

  • Anforderung: GET /v1/greeter/world
  • Antwort: { "message": "Hello world" }

Wenn der Server so konfiguriert ist, dass jede Anforderung protokolliert wird, zeigen die Serverprotokolle, dass der HTTP-Aufruf von einem gRPC-Dienst ausgeführt wird. Die Transcodierung ordnet die eingehende HTTP-Anforderung einer gRPC-Nachricht zu und konvertiert die Antwortnachricht in JSON.

info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/1.1 GET https://localhost:5001/v1/greeter/world
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint 'gRPC - /v1/greeter/{name}'
info: Server.GreeterService[0]
      Sending hello to world
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint 'gRPC - /v1/greeter/{name}'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished in 1.996ms 200 application/json

Hinzufügen von Anmerkungen zu gRPC-Methoden

gRPC-Methoden müssen mit einer HTTP-Regel versehen werden, damit sie die Transcodierung unterstützen. Die HTTP-Regel enthält Informationen darüber, wie die gRPC-Methode aufgerufen werden muss, z. B. als HTTP-Methode und Route.

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {
    option (google.api.http) = {
      get: "/v1/greeter/{name}"
    };
  }
}

Beispiel für die Vorgehensweise:

  • Definiert einen Greeter-Dienst mit einer SayHello-Methode. Die Methode verfügt über eine HTTP-Regel, die mithilfe des Namens google.api.httpangegeben wird.
  • Auf die Methode kann mit GET-Anforderungen und der /v1/greeter/{name}-Route zugegriffen werden.
  • Das name-Feld in der Anforderungsnachricht ist an einen Routenparameter gebunden.

Es stehen viele Optionen zum Anpassen der Bindung einer gRPC-Methode an eine RESTful-API zur Verfügung. Weitere Informationen zum Versehen von gRPC-Methoden mit Anmerkungen und zum Anpassen von JSON finden Sie unter Konfigurieren von HTTP und JSON für gRPC JSON-Transcodierung.

Streamingmethoden

Herkömmliches gRPC über HTTP/2 unterstützt das Streamen in alle Richtungen. Die Transcodierung ist nur auf Serverstreaming beschränkt. Client- und bidirektionale Streamingmethoden werden nicht unterstützt.

Serverstreamingmethoden verwenden durch Zeilen getrenntes JSON. Jede mit WriteAsync geschriebene Nachricht wird in JSON serialisiert und von einer neuen Zeile begleitet.

Die folgende Serverstreamingmethode schreibt drei Nachrichten:

public override async Task StreamingFromServer(ExampleRequest request,
    IServerStreamWriter<ExampleResponse> responseStream, ServerCallContext context)
{
    for (var i = 1; i <= 3; i++)
    {
        await responseStream.WriteAsync(new ExampleResponse { Text = $"Message {i}" });
        await Task.Delay(TimeSpan.FromSeconds(1));
    }
}

Der Client empfängt drei durch Zeilen getrennte JSON-Objekte:

{"Text":"Message 1"}
{"Text":"Message 2"}
{"Text":"Message 3"}

Beachten Sie, dass die WriteIndentedJSON-Einstellung nicht für Serverstreamingmethoden gilt. Die automatische Strukturierung und Einrückung fügt neue Zeilen und Leerzeichen zu JSON hinzu, die nicht mit durch Zeilen getrenntes JSON verwendet werden können.

Zeigen Sie ein Beispiel für eine ASP.NET Core gPRC-Transcodierungs- und Streaming-App an, oder laden Sie es herunter.

HTTP-Protokoll

Die im . NET SDK enthaltene ASP.NET Core gRPC-Dienstvorlage erstellt eine App, die nur für HTTP/2 konfiguriert ist. HTTP/2 ist eine geeignete Standardeinstellung, wenn eine App nur herkömmliches gRPC über HTTP/2 unterstützt. Die Transcodierung funktioniert jedoch sowohl mit HTTP/1.1 als auch mit HTTP/2. Einige Plattformen, z. B. UWP oder Unity, können HTTP/2 nicht verwenden. Um alle Client-Apps zu unterstützen, konfigurieren Sie den Server so, dass HTTP/1.1 und HTTP/2 aktiviert sind.

Ändern Sie das Standardprotokoll in appsettings.json:

{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1AndHttp2"
    }
  }
}

Alternativ können Sie Kestrel-Endpunkte im Startcode konfigurieren.

Das Aktivieren von HTTP/1.1 und HTTP/2 für denselben Port erfordert TLS für die Protokollaushandlung. Weitere Informationen zum Konfigurieren von HTTP-Protokollen in einer gRPC-App finden Sie unter ASP.NET Core gRPC-Protokollaushandlung.

gRPC JSON-Transcodierung im Vergleich zu gRPC-Web

Die Transcodierung und gRPC-Web ermöglichen es, gRPC-Dienste in einem Browser aufzurufen. Die Vorgehensweise unterscheidet sich jedoch:

  • Mit gRPC-Web können Browser-Apps gRPC-Dienste mithilfe des gRPC-Web-Client und Protobuf über den Browser aufrufen. gRPC-Web erfordert, dass die Browser-App einen gRPC-Client generiert, und hat den Vorteil, dass kleine, schnelle Protobuf-Nachrichten gesendet werden.
  • Die Transcodierung ermöglicht es Browser-Apps, gRPC-Dienste so aufzurufen, als wären sie RESTful-APIs mit JSON. Die Browser-App muss keinen gRPC-Client generieren und benötigt keine Informationen zu gRPC.

Der vorherige Greeter-Dienst kann mithilfe von JavaScript-APIs für den Browser aufgerufen werden:

var name = nameInput.value;

fetch('/v1/greeter/' + name)
  .then((response) => response.json())
  .then((result) => {
    console.log(result.message);
    // Hello world
  });

grpc-gateway

gRPC-Gateway ist eine weitere Technologie, um RESTful-JSON-APIs aus gRPC-Diensten zu erstellen. Es werden die gleichen .proto-Anmerkungen verwendet, um HTTP-Konzepte gRPC-Diensten zuzuordnen.

grpc-gateway verwendet Code-Generierung, um einen Reverse-Proxyserver zu erstellen. Der Reverseproxy übersetzt RESTful-Aufrufe in gRPC+Protobuf und sendet die Aufrufe über HTTP/2 an den gRPC-Dienst. Der Nutzen dieses Ansatzes ist, dass der gRPC-Dienst die RESTful JSON-APIs nicht kennt. Jeder gRPC-Server kann grpc-gateway verwenden.

Währenddessen wird die gRPC JSON-Transcodierung in einer ASP.NET Core-App ausgeführt. Es deserialisiert JSON in Protobuf-Nachrichten und ruft dann den gRPC-Dienst direkt auf. Die Transcodierung in ASP.NET Core bietet Vorteile für Entwickler von .NET-Apps:

  • Weniger komplex: Sowohl gRPC-Dienste als auch zugeordnete RESTful JSON-API laufen aus einer ASP.NET Core-App heraus.
  • Bessere Leistung: Die Transcodierung deserialisiert JSON in Protobuf-Nachrichten und ruft den gRPC-Dienst direkt auf. Es gibt erhebliche Leistungsvorteile bei dieser In-Process-Ausführung und zum Erstellen eines neuen gRPC-Aufrufs an einen anderen Server.
  • Geringere Kosten: Weniger Server führen zu einer kleineren monatlichen Hostingrechnung.

Weitere Informationen zur Installation und Verwendung von grpc-gateway finden Sie in der INFODATEI zu grpc-gateway.

Zusätzliche Ressourcen