Transcodifica JSON gRPC in ASP.NET Core

Nota

Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 8 di questo articolo.

Avviso

Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere Criteri di supporto di .NET e .NET Core. Per la versione corrente, vedere la versione .NET 8 di questo articolo.

Importante

Queste informazioni si riferiscono a un prodotto non definitive che può essere modificato in modo sostanziale prima che venga rilasciato commercialmente. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.

Per la versione corrente, vedere la versione .NET 8 di questo articolo.

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 ruolo importante nelle app moderne. La compilazione di API Web gRPC e JSON comporta un sovraccarico indesiderato per lo sviluppo di app.

Questo documento illustra come creare API Web JSON usando i servizi gRPC.

Panoramica

la transcodifica JSON gRPC è un'estensione per ASP.NET Core che crea API JSON RESTful per 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
  • Richieste/risposte JSON

GRPC può comunque essere usato per chiamare i servizi.

Nota

La transcodifica JSON gRPC 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 può ora essere richiamato come gRPC e come API Web JSON:

  • 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 RESTful. Per altre informazioni sull'annotazione dei metodi gRPC e sulla personalizzazione di JSON, vedere Configurare HTTP e JSON per la transcodifica JSON gRPC.

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 json delimitato da righe. 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 JSON delimitati da righe:

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

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

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 JSON gRPC 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 API RESTful 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 di API JSON RESTful dai 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 le chiamate RESTful in gRPC+Protobuf e invia le chiamate su HTTP/2 al servizio gRPC. Il vantaggio di questo approccio è che il servizio gRPC non conosce le API RESTful JSON. Qualsiasi server gRPC può usare grpc-gateway.

Nel frattempo, la transcodifica JSON gRPC 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 JSON RESTful mappata esauriscono un'app ASP.NET Core.
  • Prestazioni migliori: la transerializzazione deserializza i messaggi JSON in 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 ruolo importante nelle app moderne. La compilazione di API Web gRPC e JSON comporta un sovraccarico indesiderato per lo sviluppo di app.

Questo documento illustra come creare API Web JSON usando i servizi gRPC.

Panoramica

la transcodifica JSON gRPC è un'estensione per ASP.NET Core che crea API JSON RESTful per 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
  • Richieste/risposte JSON

GRPC può comunque essere usato per chiamare i servizi.

Nota

La transcodifica JSON gRPC 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 può ora essere richiamato come gRPC e come API Web JSON:

  • 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 RESTful. Per altre informazioni sull'annotazione dei metodi gRPC e sulla personalizzazione di JSON, vedere Configurare HTTP e JSON per la transcodifica JSON gRPC.

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 json delimitato da righe. 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 JSON delimitati da righe:

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

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

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 JSON gRPC 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 API RESTful 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 di API JSON RESTful dai 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 le chiamate RESTful in gRPC+Protobuf e invia le chiamate su HTTP/2 al servizio gRPC. Il vantaggio di questo approccio è che il servizio gRPC non conosce le API RESTful JSON. Qualsiasi server gRPC può usare grpc-gateway.

Nel frattempo, la transcodifica JSON gRPC 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 JSON RESTful mappata esauriscono un'app ASP.NET Core.
  • Prestazioni migliori: la transerializzazione deserializza i messaggi JSON in 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