Partilhar via


Transcodificação JSON gRPC em ASP.NET Core

Observação

Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 10 deste artigo.

Advertência

Esta versão do ASP.NET Core não é mais suportada. Para obter mais informações, consulte a Política de suporte do .NET e do .NET Core. Para a versão atual, consulte a versão .NET 9 deste artigo.

Por James Newton-King

gRPC é um framework de Chamadas Remotas de Procedimentos (RPC) de alto desempenho. O gRPC utiliza HTTP/2, streaming, Protobuf e contratos de mensagens para criar serviços de alto desempenho e tempo real.

Uma limitação do gRPC é que nem todas as plataformas podem usá-lo. Os navegadores não suportam totalmente o HTTP/2, tornando REST as APIs e o JSON a principal forma de transferir dados para as aplicações do navegador. Apesar dos benefícios que o gRPC traz, REST as APIs e o JSON têm um lugar importante nas aplicações modernas. Construir APIs Web gRPC e JSON acrescenta sobrecarga indesejada ao desenvolvimento de aplicações.

Este documento discute como criar APIs Web JSON usando serviços gRPC.

Visão geral

A extensão de transcodificação JSON gRPC para ASP.NET Core permite a criação de APIs JSON RESTful para serviços gRPC. Uma vez configurada, a transcodificação permite que as aplicações chamem serviços gRPC com conceitos HTTP familiares:

  • Verbos HTTP
  • Ligação de parâmetros URL
  • Pedidos/respostas JSON

o gRPC ainda pode ser usado para chamar serviços.

Observação

a transcodificação JSON gRPC substitui a API HTTP gRPC, uma extensão experimental alternativa.

Usage

  1. Adicione uma referência de pacote a Microsoft.AspNetCore.Grpc.JsonTranscoding.

  2. Registe a transcodificação durante a inicialização do servidor, adicionando AddJsonTranscoding: No ficheiro Program.cs, altere builder.Services.AddGrpc(); para builder.Services.AddGrpc().AddJsonTranscoding();.

  3. Adicionar <IncludeHttpRuleProtos>true</IncludeHttpRuleProtos> ao grupo de propriedades no ficheiro do projeto (.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. Anotar os métodos gRPC nos seus .proto ficheiros com associações e rotas 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;
    }
    

O SayHello método gRPC pode agora ser invocado como gRPC e como uma API Web JSON:

  • Pedido: GET /v1/greeter/world
  • Resposta: { "message": "Hello world" }

Se o servidor estiver configurado para escrever registos para cada pedido, os registos do servidor mostram que um serviço gRPC executa a chamada HTTP. A transcodificação mapeia o pedido HTTP recebido para uma mensagem gRPC e converte a mensagem de resposta para 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

Anotar métodos gRPC

Os métodos gRPC devem ser anotados com uma regra HTTP antes de suportarem transcodificação. A regra HTTP inclui informações sobre como chamar o método gRPC, como o método HTTP e a rota.

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

O exemplo do processo:

  • Define um Greeter serviço com um SayHello método. O método tem uma regra HTTP especificada usando o nome google.api.http.
  • O método é acessível com GET requisições e com a /v1/greeter/{name} rota.
  • O name campo na mensagem de pedido está associado a um parâmetro de rota.

Existem muitas opções disponíveis para personalizar a forma como um método gRPC se liga a uma API RESTful. Para mais informações sobre anotação de métodos gRPC e personalização de JSON, consulte Configurar HTTP e JSON para transcodificação JSON gRPC.

Métodos de streaming

O gRPC tradicional sobre HTTP/2 suporta streaming em todas as direções. A transcodificação está limitada apenas ao streaming de servidores. O streaming de clientes e os métodos de streaming bidirecional não são suportados.

Os métodos de streaming de servidor utilizam JSON delimitado por linhas. Cada mensagem escrita usando WriteAsync é serializada em JSON e seguida por uma nova linha.

O seguinte método de streaming de servidor escreve três mensagens:

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

O cliente recebe três objetos JSON delimitados por linhas:

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

Note que a WriteIndented definição JSON não se aplica a métodos de streaming de servidores. A formatação elegante adiciona novas linhas e espaços em branco ao JSON, o que impossibilita o seu uso com JSON delimitado por linhas.

Veja ou descarregue um exemplo de aplicação de transcodificação e streaming ASP.NET Core gPRC.

Protocolo HTTP

O modelo de serviço gRPC ASP.NET Core, incluído no SDK .NET, cria uma aplicação que está configurada apenas para HTTP/2. HTTP/2 é um bom padrão quando uma aplicação só suporta gRPC tradicional sobre HTTP/2. A transcodificação, no entanto, funciona tanto com HTTP/1.1 como com HTTP/2. Algumas plataformas, como UWP ou Unity, não conseguem usar HTTP/2. Para suportar todas as aplicações clientes, configure o servidor para ativar HTTP/1.1 e HTTP/2.

Atualize o protocolo predefinido em appsettings.json:

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

Alternativamente, configura Kestrel os endpoints no código de arranque.

Ativar HTTP/1.1 e HTTP/2 na mesma porta requer TLS para negociação de protocolos. Para mais informações sobre a configuração de protocolos HTTP numa aplicação gRPC, consulte ASP.NET Negociação do protocolo Core gRPC.

Transcodificação JSON gRPC vs gRPC-Web

Tanto a transcodificação como o gRPC-Web permitem que os serviços gRPC sejam chamados a partir de um navegador. No entanto, a forma como cada um faz isto é diferente:

  • O gRPC-Web permite que as aplicações do navegador chamem serviços gRPC a partir do navegador com o cliente gRPC-Web e o Protobuf. O gRPC-Web exige que a aplicação do navegador gere um cliente gRPC e tem a vantagem de enviar mensagens Protobuf pequenas e rápidas.
  • A transcodificação permite que aplicações de navegador chamem serviços gRPC como se fossem APIs RESTful com JSON. A aplicação de navegador não precisa de gerar um cliente gRPC nem de saber nada sobre gRPC.

O serviço anterior Greeter pode ser chamado usando APIs JavaScript do navegador:

var name = nameInput.value;

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

grpc-gateway

grpc-gateway é outra tecnologia para criar APIs JSON RESTful a partir de serviços gRPC. Utiliza as mesmas .proto anotações para mapear conceitos HTTP para serviços gRPC.

O grpc-gateway utiliza geração de código para criar um servidor proxy reverso. O proxy inverso traduz chamadas RESTful em gRPC+Protobuf e envia as chamadas via HTTP/2 para o serviço gRPC. A vantagem desta abordagem é que o serviço gRPC não conhece as APIs JSON RESTful. Qualquer servidor gRPC pode usar grpc-gateway.

Entretanto, a transcodificação JSON gRPC corre dentro de uma aplicação ASP.NET Core. Desserializa JSON em mensagens Protobuf e depois invoca diretamente o serviço gRPC. A transcodificação no ASP.NET Core oferece vantagens aos desenvolvedores de aplicações .NET:

  • Menos complexo: Tanto os serviços gRPC como a API JSON RESTful mapeada funcionam a partir de uma ASP.NET aplicação Core.
  • Melhor desempenho: A transcodificação desserializa mensagens JSON para Protobuf e invoca diretamente o serviço gRPC. Existem benefícios significativos de desempenho em fazer isto em processo em comparação com fazer uma nova chamada gRPC para outro servidor.
  • Custo mais baixo: Menos servidores resultam numa fatura mensal de alojamento menor.

Para instalação e utilização do grpc-gateway, consulte o README grpc-gateway.

Recursos adicionais

gRPC é um framework de Chamadas Remotas de Procedimentos (RPC) de alto desempenho. O gRPC utiliza HTTP/2, streaming, Protobuf e contratos de mensagens para criar serviços de alto desempenho e tempo real.

Uma limitação do gRPC é que nem todas as plataformas podem usá-lo. Os navegadores não suportam totalmente o HTTP/2, tornando REST as APIs e o JSON a principal forma de transferir dados para as aplicações do navegador. Apesar dos benefícios que o gRPC traz, REST as APIs e o JSON têm um lugar importante nas aplicações modernas. Construir APIs Web gRPC e JSON acrescenta sobrecarga indesejada ao desenvolvimento de aplicações.

Este documento discute como criar APIs Web JSON usando serviços gRPC.

Visão geral

A extensão de transcodificação JSON gRPC para ASP.NET Core permite a criação de APIs JSON RESTful para serviços gRPC. Uma vez configurada, a transcodificação permite que as aplicações chamem serviços gRPC com conceitos HTTP familiares:

  • Verbos HTTP
  • Ligação de parâmetros URL
  • Pedidos/respostas JSON

o gRPC ainda pode ser usado para chamar serviços.

Observação

a transcodificação JSON gRPC substitui a API HTTP gRPC, uma extensão experimental alternativa.

Usage

  1. Adicione uma referência de pacote a Microsoft.AspNetCore.Grpc.JsonTranscoding.
  2. Registe a transcodificação durante a inicialização do servidor, adicionando AddJsonTranscoding: No ficheiro Program.cs, altere builder.Services.AddGrpc(); para builder.Services.AddGrpc().AddJsonTranscoding();.
  3. Crie a estrutura /google/api de diretórios no diretório do projeto que contém o .csproj ficheiro.
  4. Adicionar google/api/http.proto e google/api/annotations.proto ficheiros ao /google/api diretório.
  5. Anotar os métodos gRPC nos seus .proto ficheiros com associações e rotas 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;
}

O SayHello método gRPC pode agora ser invocado como gRPC e como uma API Web JSON:

  • Pedido: GET /v1/greeter/world
  • Resposta: { "message": "Hello world" }

Se o servidor estiver configurado para escrever registos para cada pedido, os registos do servidor mostram que um serviço gRPC executa a chamada HTTP. A transcodificação mapeia o pedido HTTP recebido para uma mensagem gRPC e converte a mensagem de resposta para 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

Anotar métodos gRPC

Os métodos gRPC devem ser anotados com uma regra HTTP antes de suportarem transcodificação. A regra HTTP inclui informações sobre como chamar o método gRPC, como o método HTTP e a rota.

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

O exemplo do processo:

  • Define um Greeter serviço com um SayHello método. O método tem uma regra HTTP especificada usando o nome google.api.http.
  • O método é acessível com GET requisições e com a /v1/greeter/{name} rota.
  • O name campo na mensagem de pedido está associado a um parâmetro de rota.

Existem muitas opções disponíveis para personalizar a forma como um método gRPC se liga a uma API RESTful. Para mais informações sobre anotação de métodos gRPC e personalização de JSON, consulte Configurar HTTP e JSON para transcodificação JSON gRPC.

Métodos de streaming

O gRPC tradicional sobre HTTP/2 suporta streaming em todas as direções. A transcodificação está limitada apenas ao streaming de servidores. O streaming de clientes e os métodos de streaming bidirecional não são suportados.

Os métodos de streaming de servidor utilizam JSON delimitado por linhas. Cada mensagem escrita usando WriteAsync é serializada em JSON e seguida por uma nova linha.

O seguinte método de streaming de servidor escreve três mensagens:

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

O cliente recebe três objetos JSON delimitados por linhas:

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

Note que a WriteIndented definição JSON não se aplica a métodos de streaming de servidores. A formatação elegante adiciona novas linhas e espaços em branco ao JSON, o que impossibilita o seu uso com JSON delimitado por linhas.

Veja ou descarregue um exemplo de aplicação de transcodificação e streaming ASP.NET Core gPRC.

Protocolo HTTP

O modelo de serviço gRPC ASP.NET Core, incluído no SDK .NET, cria uma aplicação que está configurada apenas para HTTP/2. HTTP/2 é um bom padrão quando uma aplicação só suporta gRPC tradicional sobre HTTP/2. A transcodificação, no entanto, funciona tanto com HTTP/1.1 como com HTTP/2. Algumas plataformas, como UWP ou Unity, não conseguem usar HTTP/2. Para suportar todas as aplicações clientes, configure o servidor para ativar HTTP/1.1 e HTTP/2.

Atualize o protocolo predefinido em appsettings.json:

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

Alternativamente, configura Kestrel os endpoints no código de arranque.

Ativar HTTP/1.1 e HTTP/2 na mesma porta requer TLS para negociação de protocolos. Para mais informações sobre a configuração de protocolos HTTP numa aplicação gRPC, consulte ASP.NET Negociação do protocolo Core gRPC.

Transcodificação JSON gRPC vs gRPC-Web

Tanto a transcodificação como o gRPC-Web permitem que os serviços gRPC sejam chamados a partir de um navegador. No entanto, a forma como cada um faz isto é diferente:

  • O gRPC-Web permite que as aplicações do navegador chamem serviços gRPC a partir do navegador com o cliente gRPC-Web e o Protobuf. O gRPC-Web exige que a aplicação do navegador gere um cliente gRPC e tem a vantagem de enviar mensagens Protobuf pequenas e rápidas.
  • A transcodificação permite que aplicações de navegador chamem serviços gRPC como se fossem APIs RESTful com JSON. A aplicação de navegador não precisa de gerar um cliente gRPC nem de saber nada sobre gRPC.

O serviço anterior Greeter pode ser chamado usando APIs JavaScript do navegador:

var name = nameInput.value;

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

grpc-gateway

grpc-gateway é outra tecnologia para criar APIs JSON RESTful a partir de serviços gRPC. Utiliza as mesmas .proto anotações para mapear conceitos HTTP para serviços gRPC.

O grpc-gateway utiliza geração de código para criar um servidor proxy reverso. O proxy inverso traduz chamadas RESTful em gRPC+Protobuf e envia as chamadas via HTTP/2 para o serviço gRPC. A vantagem desta abordagem é que o serviço gRPC não conhece as APIs JSON RESTful. Qualquer servidor gRPC pode usar grpc-gateway.

Entretanto, a transcodificação JSON gRPC corre dentro de uma aplicação ASP.NET Core. Desserializa JSON em mensagens Protobuf e depois invoca diretamente o serviço gRPC. A transcodificação no ASP.NET Core oferece vantagens aos desenvolvedores de aplicações .NET:

  • Menos complexo: Tanto os serviços gRPC como a API JSON RESTful mapeada funcionam a partir de uma ASP.NET aplicação Core.
  • Melhor desempenho: A transcodificação desserializa mensagens JSON para Protobuf e invoca diretamente o serviço gRPC. Existem benefícios significativos de desempenho em fazer isto em processo em comparação com fazer uma nova chamada gRPC para outro servidor.
  • Custo mais baixo: Menos servidores resultam numa fatura mensal de alojamento menor.

Para instalação e utilização do grpc-gateway, consulte o README grpc-gateway.

Recursos adicionais