Share via


Configurar HTTP e JSON para transcodificação gRPC JSON.

Por James Newton-King

A transcodificação gRPC JSON cria APIs Web RESTful JS a partir de métodos gRPC. Usa anotações e opções para personalizar como uma API RESTful é mapeada para os métodos gRPC.

Regras HTTP

Os métodos gRPC devem ser anotados com uma regra HTTP antes de dar suporte à 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 o branch padrão do repositório, que representa o desenvolvimento atual da próxima versão do .NET. Para selecionar uma marca para uma versão específica, use a lista suspensa para Alternar branches ou marcas. Para saber mais, confira Como selecionar uma marca de versão do código-fonte do ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Método HTTP

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

  • get
  • put
  • post
  • delete
  • patch

O campo custom permite outros métodos HTTP.

No exemplo a seguir, o método CreateAddress é mapeado para POST com a rota especificada:

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

Rota

As rotas de transcodificação gRPC JSON dão suporte a parâmetros de rota. Por exemplo, {name} em uma rota associada ao campo name na mensagem de solicitação.

Para associar um campo em uma mensagem aninhada, especifique o caminho para o campo. No exemplo a seguir, {params.org} associa-se ao campo org na mensagem IssueParams:

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 de ASP.NET Core têm uma sintaxe e um conjunto de recursos semelhantes. No entanto, alguns recursos de roteamento de ASP.NET Core não são compatíveis com a transcodificação. Estão incluídos:

Corpo da solicitação

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

No exemplo a seguir, o corpo da solicitação HTTP é desserializado para o campo address:

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

Todos os campos na mensagem de solicitação que não estão associados por parâmetros de rota ou pelo corpo da solicitação 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:

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

Corpo da resposta

Por padrão, a transcodificação serializa toda a mensagem de resposta como JSON. O campo response_body 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 campo address é serializado para o corpo da resposta como JSON.

Especificação

Para saber mais sobre como personalizar a transcodificação gRPC, confira a especificação HttpRule.

Personalizar JSON

As mensagens são convertidas de JSON usando o mapeamento JSON na especificação Protobuf. O mapeamento JSON de Protobuf é uma maneira padronizada de conversão entre JSON e Protobuf, e toda serialização segue essas regras.

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

Opção Valor padrão Descrição
IgnoreDefaultValues false Se definido como true, os campos com valores padrão serão ignorados durante a serialização.
WriteEnumsAsIntegers false Se definido como true, os valores de enumeração serão gravados como inteiros em vez de cadeias de caracteres.
WriteInt64sAsStrings false Se definido como true, os valores Int64 e UInt64 serão gravados como cadeias de caracteres em vez de números.
WriteIndented false Se definido como true, JSON será gravado usando uma reformatação automática. Essa opção não afeta os métodos de streaming, que gravam mensagens JSON delimitadas por linha e não podem usar uma reformatação automática.
builder.Services.AddGrpc().AddJsonTranscoding(o =>
{
    o.JsonSettings.WriteIndented = true;
});

No arquivo .proto, a opção json_name de campo personaliza o nome de um campo quando ele é serializado como JSON, como no exemplo a seguir:

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

A transcodificação não dá suporte à personalização avançada de JSON. Os aplicativos que exigem um controle de estrutura preciso de JSON devem considerar o uso da API Web ASP.NET Core.

Recursos adicionais