Partilhar via


Configurar HTTP e JSON para a transcodificação de JSON em gRPC

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

a transcodificação JSON gRPC cria APIs web JSON RESTful a partir de métodos gRPC. Utiliza anotações e opções para personalizar como uma API RESTful corresponde aos métodos gRPC.

Regras HTTP

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 uma API RESTful, como o método HTTP e a rota.

import "google/api/annotations.proto";

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

Uma regra HTTP é:

Observação

Os links de documentação para a fonte de referência do .NET geralmente carregam a ramificação padrão do repositório, que representa o desenvolvimento atual para a próxima versão do .NET. Para selecionar uma tag para uma versão específica, use a lista suspensa Alternar entre ramificações ou tags. Para obter mais informações, consulte Como selecionar uma marca de versão do código-fonte ASP.NET Core (dotnet/AspNetCore.Docs #26205).

método HTTP

O método HTTP é especificado definindo a rota para o nome correspondente do campo do método HTTP:

  • get
  • put
  • post
  • delete
  • patch

O custom campo permite outros métodos HTTP.

No exemplo seguinte, o método CreateAddress é mapeado em POST com a rota especificada.

service Address {
  rpc CreateAddress (CreateAddressRequest) returns (CreateAddressReply) {
    option (google.api.http) = {
      post: "/v1/address",
      body: "*"
    };
  }
}

Percurso

As rotas de transcodificação JSON gRPC suportam parâmetros de rota. Por exemplo, {name} numa rota associa-se ao campo name na mensagem de pedido.

Para atribuir um campo a uma mensagem aninhada, especifique o caminho até ao campo. No exemplo seguinte, {params.org} liga-se ao org campo na IssueParams mensagem:

service Repository {
  rpc GetIssue (GetIssueRequest) returns (GetIssueReply) {
    option (google.api.http) = {
      get: "/{apiVersion}/{params.org}/{params.repo}/issue/{params.issueId}"
    };
  }
}

message GetIssueRequest {
  int32 api_version = 1;
  IssueParams params = 2;
}
message IssueParams {
  string org = 1;
  string repo = 2;
  int32 issueId = 3;
}

Rotas de transcodificação e rotas ASP.NET Core têm uma sintaxe e conjunto de funcionalidades semelhantes. No entanto, alguns recursos de encaminhamento do ASP.NET Core não são suportados pela transcodificação. Estes são, entre outros:

Corpo de solicitação

A transcodificação desserializa o JSON do corpo do pedido para a mensagem correspondente. O body campo especifica como o corpo do pedido HTTP é traduzido para a mensagem do pedido. O valor é ou o nome do campo de pedido cujo valor está mapeado para o corpo do pedido HTTP ou * para mapear todos os campos de pedido.

No exemplo seguinte, o corpo do pedido HTTP é deserializado para o address campo:

service Address {
  rpc AddAddress (AddAddressRequest) returns (AddAddressReply) {
    option (google.api.http) = {
      post: "/{apiVersion}/address",
      body: "address"
    };
  }
}

message AddAddressRequest {
  int32 api_version = 1;
  Address address = 2;
}
message Address {
  string street = 1;
  string city = 2;
  string country = 3;
}

Parâmetros de consulta

Quaisquer campos na mensagem de pedido que não estejam limitados por parâmetros de rota ou pelo corpo do pedido podem ser definidos usando parâmetros de consulta HTTP.

service Repository {
  rpc GetIssues (GetIssuesRequest) returns (GetIssuesReply) {
    option (google.api.http) = {
      get: "/v1/{org}/{repo}/issue"
    };
  }
}

message GetIssuesRequest {
  string org = 1;
  string repo = 2;
  string text = 3;
  PageParams page = 4;
}
message PageParams {
  int32 index = 1;
  int32 size = 2;
}

No exemplo anterior:

  • org e repo campos são vinculados a partir dos parâmetros da rota.
  • Outros campos, como text e os campos aninhados de page, podem ser associados a partir da cadeia de consulta: ?text=value&page.index=0&page.size=10

Corpo da resposta

Por defeito, a transcodificação serializa toda a mensagem de resposta como JSON. O response_body campo permite a serialização de um subconjunto da mensagem de resposta.

service Address {
  rpc GetAddress (GetAddressRequest) returns (GetAddressReply) {
    option (google.api.http) = {
      get: "/v1/address/{id}",
      response_body: "address"
    };
  }
}

message GetAddressReply {
  int32 version = 1;
  Address address = 2;
}
message Address {
  string street = 1;
  string city = 2;
  string country = 3;
}

No exemplo anterior, o address campo é serializado para o corpo de resposta como JSON.

Specification

Para mais informações sobre a personalização da transcodificação gRPC, consulte a especificação HttpRule.

Personalizar JSON

As mensagens são convertidas para e a partir de JSON usando o mapeamento JSON na especificação Protobuf. O mapeamento JSON do Protobuf é uma forma padronizada de converter entre JSON e Protobuf, e toda a serialização segue estas regras.

No entanto, a transcodificação JSON gRPC oferece algumas opções limitadas para personalizar JSON com GrpcJsonSettings, como mostrado na tabela seguinte.

Opção Valor padrão Description
IgnoreDefaultValues false Se definidos para true, os campos com valores predefinidos são ignorados durante a serialização.
WriteEnumsAsIntegers false Se definidos para true, os valores de enum são escritos como inteiros em vez de cadeias.
WriteInt64sAsStrings false Se definido como true, Int64 e UInt64 os valores são escritos como cadeias em vez de números.
WriteIndented false Se definido para true, o JSON é escrito usando formatação legível. Esta opção não afeta os métodos de streaming, que escrevem mensagens JSON delimitadas por linhas e não conseguem usar impressão bonita.
builder.Services.AddGrpc().AddJsonTranscoding(o =>
{
    o.JsonSettings.WriteIndented = true;
});

No .proto ficheiro, a json_name opção de campo personaliza o nome de um campo quando este é serializado como JSON, como no seguinte exemplo:

message TestMessage {
  string my_field = 1 [json_name="customFieldName"];
}

A transcodificação não suporta personalização avançada de JSON. As aplicações que exigem controlo preciso da estrutura JSON devem considerar usar ASP.NET API Web Core.

Recursos adicionais