Compartir a través de


Configuración de HTTP y JSON para la transcodificación de JSON de gRPC

Por James Newton-King

La transcodificación JSON de gRPC crea API web RESTful JSON a partir de métodos gRPC. Usa anotaciones y opciones para personalizar cómo se asigna una API RESTful a los métodos gRPC.

Reglas HTTP

Los métodos gRPC deben anotarse con una regla HTTP antes de admitir la transcodificación. La regla HTTP incluye información sobre cómo llamar al método gRPC como una API RESTful, como el método HTTP y la ruta.

import "google/api/annotations.proto";

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

Una regla HTTP es:

Nota

Los vínculos de la documentación al origen de referencia de .NET cargan normalmente la rama predeterminada del repositorio, que representa el desarrollo actual para la próxima versión de .NET. Para seleccionar una etiqueta de una versión específica, use la lista desplegable Cambiar ramas o etiquetas. Para obtener más información, vea Procedimientos para seleccionar una etiqueta de versión de código fuente de ASP.NET Core (dotnet/AspNetCore.Docs #26205).

HTTP method

El método HTTP se especifica estableciendo la ruta en el nombre del campo del método HTTP coincidente:

  • get
  • put
  • post
  • delete
  • patch

El campo custom permite otros métodos HTTP.

En el ejemplo siguiente, el método CreateAddress se asigna a POST con la ruta especificada:

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

Enrutar

Las rutas de transcodificación JSON de gRPC admiten parámetros de ruta. Por ejemplo, {name} en una ruta se enlaza al campo name en el mensaje de solicitud.

Para enlazar un campo en un mensaje anidado, especifique la ruta de acceso al campo. En el ejemplo siguiente, {params.org} se enlaza al campo org del mensaje 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;
}

Las rutas de transcodificación y las rutas de ASP.NET Core tienen una sintaxis y un conjunto de características similares. Sin embargo, algunas características de enrutamiento de ASP.NET Core no son compatibles con la transcodificación. Entre ellas se incluyen las siguientes:

Cuerpo de la solicitud

La transcodificación deserializa el JSON del cuerpo de la solicitud en el mensaje de solicitud. El campo body especifica cómo se asigna el cuerpo de la solicitud HTTP al mensaje de solicitud. El valor es el nombre del campo de solicitud cuyo valor se asigna al cuerpo de la solicitud HTTP o * para asignar todos los campos de solicitud.

En el ejemplo siguiente, el cuerpo de la solicitud HTTP se deserializa en el 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

Los campos del mensaje de solicitud que no están enlazados por parámetros de ruta o el cuerpo de la solicitud se pueden establecer mediante 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;
}

En el ejemplo anterior:

  • Los campos org y repo se enlazan a partir de parámetros de ruta.
  • Otros campos, como text y los campos anidados de page, se pueden enlazar desde la cadena de consulta: ?text=value&page.index=0&page.size=10

Response body

De forma predeterminada, la transcodificación serializa todo el mensaje de respuesta como JSON. El campo response_body permite la serialización de un subconjunto del mensaje de respuesta.

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

En el ejemplo anterior, el campo address se serializa en el cuerpo de la respuesta como JSON.

Especificación

Para obtener más información sobre cómo personalizar la transcodificación de gRPC, consulte la especificación HttpRule.

Personalización de JSON

Los mensajes se convierten en y desde JSON mediante la asignación JSON en la especificación Protobuf. La asignación JSON de Protobuf es una manera estandarizada de convertir entre JSON y Protobuf, y toda la serialización sigue estas reglas.

Sin embargo, la transcodificación JSON de gRPC ofrece algunas opciones limitadas para personalizar JSON con GrpcJsonSettings, como se muestra en la tabla siguiente.

Opción Valor predeterminado Descripción
IgnoreDefaultValues false Si se establece en true, los campos con valores predeterminados se omiten durante la serialización.
WriteEnumsAsIntegers false Si se establece en true, los valores de enumeración se escriben como enteros en lugar de cadenas.
WriteInt64sAsStrings false Si se establece en true, los valores Int64 y UInt64 se escriben como cadenas en lugar de números.
WriteIndented false Si se establece en true, JSON se escribe con una impresión con sangría. Esta opción no afecta a los métodos de streaming, que escriben mensajes JSON delimitados por líneas y no pueden usar una impresión con sangría.
builder.Services.AddGrpc().AddJsonTranscoding(o =>
{
    o.JsonSettings.WriteIndented = true;
});

En el archivo .proto, la opción del campo json_name personaliza el nombre de un campo cuando se serializa como JSON, como en el ejemplo siguiente:

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

La transcodificación no admite la personalización avanzada de JSON. Las aplicaciones que requieren un control preciso de la estructura JSON deben considerar el uso de la API web de ASP.NET Core.

Recursos adicionales