Transcodifica gRPC JSON in ASP.NET Core

Di James Newton-King

gRPC è un framework RPC (Remote Procedure Call) ad alte prestazioni. gRPC usa contratti HTTP/2, streaming, Protobuf e message per creare servizi a prestazioni elevate e in tempo reale.

Una limitazione con gRPC è che non tutte le piattaforme possono usarlo. I browser non supportano completamente HTTP/2, rendendo REST le API e JSON il modo principale per ottenere i dati nelle app del browser. Nonostante i vantaggi offerti da gRPC, REST le API e JSON hanno un posto importante nelle app moderne. La creazione di API Web gRPC eJSON comporta un sovraccarico indesiderato per lo sviluppo di app.

Questo documento illustra come creare JSAPI Web ON usando i servizi gRPC.

Panoramica

la transcodifica gRPC JSON è un'estensione per ASP.NET Core che crea RESTAPI ON con ful JSper i servizi gRPC. Dopo la configurazione, la transcodifica consente alle app di chiamare i servizi gRPC con concetti HTTP familiari:

  • Verbi HTTP
  • Associazione di parametri URL
  • JSRichieste/risposte ON

GRPC può comunque essere usato per chiamare i servizi.

Nota

la transcodifica gRPC JSON sostituisce l'API HTTP gRPC, un'estensione sperimentale alternativa.

Utilizzo

  1. Aggiungere un riferimento al pacchetto a Microsoft.AspNetCore.Grpc.JsonTranscoding.

  2. Registrare la transcodifica nel codice di avvio del Program.cs server aggiungendo AddJsonTranscoding: nel file passare builder.Services.AddGrpc(); a builder.Services.AddGrpc().AddJsonTranscoding();.

  3. Aggiungere <IncludeHttpRuleProtos>true</IncludeHttpRuleProtos> al gruppo di proprietà nel file di progetto (.csproj):

    <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. Annotare i metodi gRPC nei .proto file con associazioni e route HTTP:

    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;
    }
    

Il SayHello metodo gRPC ora può essere richiamato come gRPC e come JSAPI Web ON:

  • Richiesta: GET /v1/greeter/world
  • Risposta: { "message": "Hello world" }

Se il server è configurato per scrivere log per ogni richiesta, i log del server mostrano che un servizio gRPC esegue la chiamata HTTP. La transcodifica esegue il mapping della richiesta HTTP in ingresso a un messaggio gRPC e converte il messaggio di risposta 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

Annotare i metodi gRPC

I metodi gRPC devono essere annotati con una regola HTTP prima di supportare la transcodifica. La regola HTTP include informazioni su come chiamare il metodo gRPC, ad esempio il metodo HTTP e la route.

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

Esempio di procedura:

  • Definisce un Greeter servizio con un SayHello metodo . Il metodo ha una regola HTTP specificata usando il nome google.api.http.
  • Il metodo è accessibile con GET le richieste e la /v1/greeter/{name} route.
  • Il name campo nel messaggio di richiesta è associato a un parametro di route.

Sono disponibili molte opzioni per personalizzare il modo in cui un metodo gRPC viene associato a un'API RESTcon nome. Per altre informazioni sull'annotazione dei metodi gRPC e sulla JSpersonalizzazione di ON, vedere Configurare HTTP e JSON per la transcodifica gRPC JSON.

Metodi di streaming

GRPC tradizionale su HTTP/2 supporta lo streaming in tutte le direzioni. La transcodifica è limitata solo al flusso server. I metodi di streaming client e di streaming bidirezionali non sono supportati.

I metodi di streaming del server usano ON delimitato da JSriga. Ogni messaggio scritto tramite WriteAsync viene serializzato in JSON e seguito da una nuova riga.

Il metodo di streaming del server seguente scrive tre messaggi:

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));
    }
}

Il client riceve tre oggetti ON delimitati da JSriga:

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

Si noti che l'impostazione WriteIndentedJSON non si applica ai metodi di streaming del server. La stampa aggiunge nuove righe e spazi vuoti a JSON, che non possono essere utilizzati con ON delimitato da JSlinea.

Visualizzare o scaricare un esempio di transcodifica e streaming di ASP.NET Core gPRC.

Protocollo HTTP

Il modello di servizio ASP.NET Core gRPC, incluso in .NET SDK, crea un'app configurata solo per HTTP/2. HTTP/2 è un'impostazione predefinita valida quando un'app supporta solo gRPC tradizionale su HTTP/2. La transcodifica, tuttavia, funziona con HTTP/1.1 e HTTP/2. Alcune piattaforme, ad esempio UWP o Unity, non possono usare HTTP/2. Per supportare tutte le app client, configurare il server per abilitare HTTP/1.1 e HTTP/2.

Aggiornare il protocollo predefinito in appsettings.json:

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

In alternativa, configurare Kestrel gli endpoint nel codice di avvio.

L'abilitazione di HTTP/1.1 e HTTP/2 nella stessa porta richiede TLS per la negoziazione del protocollo. Per altre informazioni sulla configurazione dei protocolli HTTP in un'app gRPC, vedere ASP.NET negoziazione del protocollo gRPC core.

transcodifica gRPC JSON e gRPC-Web

Sia la transcodifica che gRPC-Web consentono di chiamare i servizi gRPC da un browser. Tuttavia, il modo in cui ognuno esegue questa operazione è diverso:

  • gRPC-Web consente alle app del browser di chiamare i servizi gRPC dal browser con il client gRPC-Web e Protobuf. gRPC-Web richiede che l'app browser generi un client gRPC e abbia il vantaggio di inviare messaggi Protobuf di piccole dimensioni e veloci.
  • La transcodifica consente alle app del browser di chiamare i servizi gRPC come se fossero RESTAPI con JSON. L'app browser non deve generare un client gRPC o sapere nulla su gRPC.

Il servizio precedente Greeter può essere chiamato usando le API JavaScript del browser:

var name = nameInput.value;

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

grpc-gateway

grpc-gateway è un'altra tecnologia per la creazione RESTdi API ON con ful JSda servizi gRPC. Usa le stesse .proto annotazioni per eseguire il mapping dei concetti HTTP ai servizi gRPC.

grpc-gateway usa la generazione di codice per creare un server proxy inverso. Il proxy inverso converte RESTle chiamateful in gRPC+Protobuf e invia le chiamate tramite HTTP/2 al servizio gRPC. Il vantaggio di questo approccio è che il servizio gRPC non conosce le RESTAPI ON con ful JS. Qualsiasi server gRPC può usare grpc-gateway.

Nel frattempo, la transcodifica gRPC JSON viene eseguita all'interno di un'app ASP.NET Core. Deserializza JSON nei messaggi Protobuf, quindi richiama direttamente il servizio gRPC. La transcodifica in ASP.NET Core offre vantaggi agli sviluppatori di app .NET:

  • Meno complesso: entrambi i servizi gRPC e l'API on con JSmapping RESThanno esaurito un'app ASP.NET Core.
  • Prestazioni migliori: la transerializzazione deserializza i JSmessaggi ON a Protobuf e richiama direttamente il servizio gRPC. Questa operazione in-process comporta notevoli vantaggi in termini di prestazioni rispetto all'esecuzione di una nuova chiamata gRPC a un server diverso.
  • Costo inferiore: un minor numero di server comporta una fattura di hosting mensile più piccola.

Per l'installazione e l'utilizzo di grpc-gateway, vedere grpc-gateway README.

Risorse aggiuntive

gRPC è un framework RPC (Remote Procedure Call) ad alte prestazioni. gRPC usa contratti HTTP/2, streaming, Protobuf e message per creare servizi a prestazioni elevate e in tempo reale.

Una limitazione con gRPC è che non tutte le piattaforme possono usarlo. I browser non supportano completamente HTTP/2, rendendo REST le API e JSON il modo principale per ottenere i dati nelle app del browser. Nonostante i vantaggi offerti da gRPC, REST le API e JSON hanno un posto importante nelle app moderne. La creazione di API Web gRPC eJSON comporta un sovraccarico indesiderato per lo sviluppo di app.

Questo documento illustra come creare JSAPI Web ON usando i servizi gRPC.

Panoramica

la transcodifica gRPC JSON è un'estensione per ASP.NET Core che crea RESTAPI ON con ful JSper i servizi gRPC. Dopo la configurazione, la transcodifica consente alle app di chiamare i servizi gRPC con concetti HTTP familiari:

  • Verbi HTTP
  • Associazione di parametri URL
  • JSRichieste/risposte ON

GRPC può comunque essere usato per chiamare i servizi.

Nota

la transcodifica gRPC JSON sostituisce l'API HTTP gRPC, un'estensione sperimentale alternativa.

Utilizzo

  1. Aggiungere un riferimento al pacchetto a Microsoft.AspNetCore.Grpc.JsonTranscoding.
  2. Registrare la transcodifica nel codice di avvio del Program.cs server aggiungendo AddJsonTranscoding: nel file passare builder.Services.AddGrpc(); a builder.Services.AddGrpc().AddJsonTranscoding();.
  3. Creare la struttura /google/api di directory nella directory del progetto che contiene il .csproj file.
  4. Aggiungere google/api/http.proto file e google/api/annotations.proto alla /google/api directory.
  5. Annotare i metodi gRPC nei .proto file con associazioni e route HTTP:
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;
}

Il SayHello metodo gRPC ora può essere richiamato come gRPC e come JSAPI Web ON:

  • Richiesta: GET /v1/greeter/world
  • Risposta: { "message": "Hello world" }

Se il server è configurato per scrivere log per ogni richiesta, i log del server mostrano che un servizio gRPC esegue la chiamata HTTP. La transcodifica esegue il mapping della richiesta HTTP in ingresso a un messaggio gRPC e converte il messaggio di risposta 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

Annotare i metodi gRPC

I metodi gRPC devono essere annotati con una regola HTTP prima di supportare la transcodifica. La regola HTTP include informazioni su come chiamare il metodo gRPC, ad esempio il metodo HTTP e la route.

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

Esempio di procedura:

  • Definisce un Greeter servizio con un SayHello metodo . Il metodo ha una regola HTTP specificata usando il nome google.api.http.
  • Il metodo è accessibile con GET le richieste e la /v1/greeter/{name} route.
  • Il name campo nel messaggio di richiesta è associato a un parametro di route.

Sono disponibili molte opzioni per personalizzare il modo in cui un metodo gRPC viene associato a un'API RESTcon nome. Per altre informazioni sull'annotazione dei metodi gRPC e sulla JSpersonalizzazione di ON, vedere Configurare HTTP e JSON per la transcodifica gRPC JSON.

Metodi di streaming

GRPC tradizionale su HTTP/2 supporta lo streaming in tutte le direzioni. La transcodifica è limitata solo al flusso server. I metodi di streaming client e di streaming bidirezionali non sono supportati.

I metodi di streaming del server usano ON delimitato da JSriga. Ogni messaggio scritto tramite WriteAsync viene serializzato in JSON e seguito da una nuova riga.

Il metodo di streaming del server seguente scrive tre messaggi:

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));
    }
}

Il client riceve tre oggetti ON delimitati da JSriga:

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

Si noti che l'impostazione WriteIndentedJSON non si applica ai metodi di streaming del server. La stampa aggiunge nuove righe e spazi vuoti a JSON, che non possono essere utilizzati con ON delimitato da JSlinea.

Visualizzare o scaricare un esempio di transcodifica e streaming di ASP.NET Core gPRC.

Protocollo HTTP

Il modello di servizio ASP.NET Core gRPC, incluso in .NET SDK, crea un'app configurata solo per HTTP/2. HTTP/2 è un'impostazione predefinita valida quando un'app supporta solo gRPC tradizionale su HTTP/2. La transcodifica, tuttavia, funziona con HTTP/1.1 e HTTP/2. Alcune piattaforme, ad esempio UWP o Unity, non possono usare HTTP/2. Per supportare tutte le app client, configurare il server per abilitare HTTP/1.1 e HTTP/2.

Aggiornare il protocollo predefinito in appsettings.json:

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

In alternativa, configurare Kestrel gli endpoint nel codice di avvio.

L'abilitazione di HTTP/1.1 e HTTP/2 nella stessa porta richiede TLS per la negoziazione del protocollo. Per altre informazioni sulla configurazione dei protocolli HTTP in un'app gRPC, vedere ASP.NET negoziazione del protocollo gRPC core.

transcodifica gRPC JSON e gRPC-Web

Sia la transcodifica che gRPC-Web consentono di chiamare i servizi gRPC da un browser. Tuttavia, il modo in cui ognuno esegue questa operazione è diverso:

  • gRPC-Web consente alle app del browser di chiamare i servizi gRPC dal browser con il client gRPC-Web e Protobuf. gRPC-Web richiede che l'app browser generi un client gRPC e abbia il vantaggio di inviare messaggi Protobuf di piccole dimensioni e veloci.
  • La transcodifica consente alle app del browser di chiamare i servizi gRPC come se fossero RESTAPI con JSON. L'app browser non deve generare un client gRPC o sapere nulla su gRPC.

Il servizio precedente Greeter può essere chiamato usando le API JavaScript del browser:

var name = nameInput.value;

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

grpc-gateway

grpc-gateway è un'altra tecnologia per la creazione RESTdi API ON con ful JSda servizi gRPC. Usa le stesse .proto annotazioni per eseguire il mapping dei concetti HTTP ai servizi gRPC.

grpc-gateway usa la generazione di codice per creare un server proxy inverso. Il proxy inverso converte RESTle chiamateful in gRPC+Protobuf e invia le chiamate tramite HTTP/2 al servizio gRPC. Il vantaggio di questo approccio è che il servizio gRPC non conosce le RESTAPI ON con ful JS. Qualsiasi server gRPC può usare grpc-gateway.

Nel frattempo, la transcodifica gRPC JSON viene eseguita all'interno di un'app ASP.NET Core. Deserializza JSON nei messaggi Protobuf, quindi richiama direttamente il servizio gRPC. La transcodifica in ASP.NET Core offre vantaggi agli sviluppatori di app .NET:

  • Meno complesso: entrambi i servizi gRPC e l'API on con JSmapping RESThanno esaurito un'app ASP.NET Core.
  • Prestazioni migliori: la transerializzazione deserializza i JSmessaggi ON a Protobuf e richiama direttamente il servizio gRPC. Questa operazione in-process comporta notevoli vantaggi in termini di prestazioni rispetto all'esecuzione di una nuova chiamata gRPC a un server diverso.
  • Costo inferiore: un minor numero di server comporta una fattura di hosting mensile più piccola.

Per l'installazione e l'utilizzo di grpc-gateway, vedere grpc-gateway README.

Risorse aggiuntive