Transcodificación JSON de gRPC en ASP.NET Core
Nota:
Esta no es la versión más reciente de este artículo. Para la versión actual, consulta la versión .NET 8 de este artículo.
Advertencia
Esta versión de ASP.NET Core ya no se admite. Para obtener más información, consulta la Directiva de soporte técnico de .NET y .NET Core. Para la versión actual, consulta la versión .NET 8 de este artículo.
Importante
Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.
Para la versión actual, consulta la versión .NET 8 de este artículo.
gRPC es un marco de llamada a procedimiento remoto (RPC) de alto rendimiento. gRPC usa HTTP/2, streaming, Protobuf y contratos de mensaje para crear servicios en tiempo real de alto rendimiento.
Una limitación de gRPC es que no se puede usar en todas las plataformas. Los exploradores no son totalmente compatibles con HTTP/2, por lo que las APIREST y JSON son la manera principal de obtener datos en aplicaciones de explorador. Incluso con las ventajas que aporta gRPC, las API REST y JSON ocupan un lugar importante en las aplicaciones modernas. La compilación de API web JSON y gRPC agrega una sobrecarga no deseada al desarrollo de aplicaciones.
En este documento se explica cómo crear API web JSON con servicios gRPC.
Información general
La transcodificación JSON de gRPC es una extensión experimental para ASP.NET Core que crea API JSON de RESTful para servicios gRPC. Una vez configurada, la transcodificación permite que las aplicaciones llamen a servicios gRPC con conceptos conocidos de HTTP:
- Verbos HTTP
- Enlace de parámetros de dirección URL
- Solicitudes y respuestas JSON
gRPC también se puede usar para llamar a servicios.
Nota:
La transcodificación JSON de gRPC reemplaza la API HTTP de gRPC, una extensión experimental alternativa.
Uso
Agregue una referencia de paquete a
Microsoft.AspNetCore.Grpc.JsonTranscoding
.Registre la transcodificación en el código de inicio del servidor agregando
AddJsonTranscoding
: en el archivoProgram.cs
, cambiebuilder.Services.AddGrpc();
porbuilder.Services.AddGrpc().AddJsonTranscoding();
.Agregue
<IncludeHttpRuleProtos>true</IncludeHttpRuleProtos>
al grupo de propiedades en el archivo de proyecto (.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>
Anote los métodos gRPC en los archivos
.proto
con enlaces y rutas 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; }
El método gRPC SayHello
ya se puede invocar como gRPC y como una API web de JSON:
- Solicitud:
GET /v1/greeter/world
- Respuesta:
{ "message": "Hello world" }
Si el servidor está configurado para escribir registros para cada solicitud, los registros de servidor muestran que la llamada HTTP se ejecuta mediante un servicio gRPC. La transcodificación asigna la solicitud HTTP entrante a un mensaje de gRPC y, luego, convierte el mensaje de respuesta en 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
Anotación de métodos gRPC
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 el método HTTP y la ruta.
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {
option (google.api.http) = {
get: "/v1/greeter/{name}"
};
}
}
El ejemplo de procedimiento:
- Define un servicio
Greeter
con un métodoSayHello
. El método tiene una regla HTTP especificada con el nombregoogle.api.http
. - El método es accesible con solicitudes
GET
y la ruta/v1/greeter/{name}
. - El campo
name
del mensaje de solicitud está enlazado a un parámetro de ruta.
Hay muchas opciones disponibles para personalizar cómo un método gRPC se enlaza a una API RESTful. Para obtener más información sobre cómo anotar métodos gRPC y personalizar JSON, consulta Configuración de HTTP y JSON para la transcodificación de JSON de gRPC.
Métodos de streaming
El gRPC tradicional a través de HTTP/2 admite el streaming en todas las direcciones. La transcodificación se limita solo al streaming del servidor. No se admiten métodos de streaming de cliente ni de streaming bidireccional.
Los métodos de streaming de servidor usan JSON delimitado por líneas. Cada mensaje escrito mediante WriteAsync
se serializa a JSON y va seguido de una nueva línea.
El siguiente método de streaming de servidor escribe tres mensajes:
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));
}
}
El cliente recibe tres objetos JSON delimitados por líneas:
{"Text":"Message 1"}
{"Text":"Message 2"}
{"Text":"Message 3"}
Ten en cuenta que la configuración de WriteIndented
JSON no se aplica a los métodos de streaming de servidor. La impresión con sangría agrega nuevas líneas y espacios en blanco a JSON, que no se pueden usar con JSON delimitado por líneas.
Vea o descargue un ejemplo de aplicación de transcodificación y streaming de gPRC para ASP.NET Core.
Protocolo HTTP
La plantilla de servicio gRPC de ASP.NET Core, incluida en el SDK de .NET, crea una aplicación que solo está configurada para HTTP/2. HTTP/2 es un buen valor predeterminado cuando una aplicación solo admite gRPC tradicional a través de HTTP/2. Sin embargo, la transcodificación funciona con HTTP/1.1 y HTTP/2. Algunas plataformas, como UWP o Unity, no pueden usar HTTP/2. Para admitir todas las aplicaciones cliente, configure el servidor para habilitar HTTP/1.1 y HTTP/2.
Actualice el protocolo predeterminado en appsettings.json
:
{
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1AndHttp2"
}
}
}
Como alternativa, configure los puntos de conexión de Kestrel en el código de inicio.
La habilitación de HTTP/1.1 y HTTP/2 en el mismo puerto requiere TLS para la negociación de protocolos. Para obtener más información sobre cómo configurar protocolos HTTP en una aplicación gRPC, consulte Negociación del protocolo gRPC de ASP.NET Core.
Transcodificación JSON de gRPC frente a gRPC-Web
Tanto la transcodificación como gRPC-Web permiten llamar a servicios gRPC desde un explorador, aunque de manera diferente:
- gRPC-Web permite a las aplicaciones de explorador llamar a servicios gRPC desde el explorador con el cliente gRPC-Web y Protobuf. gRPC-Web requiere que la aplicación de explorador genere un cliente gRPC y tiene la ventaja de que envía mensajes de Protobuf pequeños y rápidos.
- La transcodificación permite a las aplicaciones de explorador llamar a servicios gRPC como si fueran API RESTful con JSON. No es necesario que la aplicación de explorador genere un cliente gRPC o que disponga de información sobre gRPC.
Se puede llamar al servicio Greeter
anterior mediante las API de JavaScript del explorador:
var name = nameInput.value;
fetch('/v1/greeter/' + name)
.then((response) => response.json())
.then((result) => {
console.log(result.message);
// Hello world
});
grpc-gateway
grpc-gateway es otra tecnología para crear API JSON de RESTful desde servicios gRPC. Usa las mismas anotaciones .proto
para asignar conceptos HTTP a servicios gRPC.
grpc-gateway utiliza la generación de código para crear un servidor proxy inverso. El proxy inverso traduce las llamadas RESTful a gRPC+Protobuf y envía las llamadas a través de HTTP/2 al servicio gRPC. La ventaja de este enfoque es que el servicio gRPC no conoce las API JSON de RESTful. Cualquier servidor gRPC puede usar grpc-gateway.
Mientras tanto, la transcodificación JSON de gRPC se ejecuta dentro de una aplicación de ASP.NET Core. Deserializa JSON en mensajes protobuf y, a continuación, invoca directamente el servicio gRPC. La transcodificación en ASP.NET Core ofrece ventajas a los desarrolladores de aplicaciones de .NET:
- Menos complejo: tanto los servicios gRPC como la API JSON RESTful asignada se ejecutan fuera de una aplicación de ASP.NET Core.
- Mejor rendimiento: la transcodificación deserializa JSON en mensajes Protobuf e invoca directamente el servicio gRPC. Hay importantes ventajas de rendimiento al hacer esto en proceso frente a realizar una nueva llamada gRPC a otro servidor.
- Menor costo: menos servidores dan lugar a una factura de hospedaje mensual más reducida.
Para obtener información sobre la instalación y el uso de grpc-gateway, consulte el archivo LÉAME de grpc-gateway.
Recursos adicionales
gRPC es un marco de llamada a procedimiento remoto (RPC) de alto rendimiento. gRPC usa HTTP/2, streaming, Protobuf y contratos de mensaje para crear servicios en tiempo real de alto rendimiento.
Una limitación de gRPC es que no se puede usar en todas las plataformas. Los exploradores no son totalmente compatibles con HTTP/2, por lo que las APIREST y JSON son la manera principal de obtener datos en aplicaciones de explorador. Incluso con las ventajas que aporta gRPC, las API REST y JSON ocupan un lugar importante en las aplicaciones modernas. La compilación de API web JSON y gRPC agrega una sobrecarga no deseada al desarrollo de aplicaciones.
En este documento se explica cómo crear API web JSON con servicios gRPC.
Información general
La transcodificación JSON de gRPC es una extensión experimental para ASP.NET Core que crea API JSON de RESTful para servicios gRPC. Una vez configurada, la transcodificación permite que las aplicaciones llamen a servicios gRPC con conceptos conocidos de HTTP:
- Verbos HTTP
- Enlace de parámetros de dirección URL
- Solicitudes y respuestas JSON
gRPC también se puede usar para llamar a servicios.
Nota:
La transcodificación JSON de gRPC reemplaza la API HTTP de gRPC, una extensión experimental alternativa.
Uso
- Agregue una referencia de paquete a
Microsoft.AspNetCore.Grpc.JsonTranscoding
. - Registre la transcodificación en el código de inicio del servidor agregando
AddJsonTranscoding
: en el archivoProgram.cs
, cambiebuilder.Services.AddGrpc();
porbuilder.Services.AddGrpc().AddJsonTranscoding();
. - Cree la estructura de directorios
/google/api
en el directorio del proyecto que contiene el archivo.csproj
. - Agregue archivos
google/api/http.proto
ygoogle/api/annotations.proto
al directorio/google/api
. - Anote los métodos gRPC en los archivos
.proto
con enlaces y rutas 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;
}
El método gRPC SayHello
ya se puede invocar como gRPC y como una API web de JSON:
- Solicitud:
GET /v1/greeter/world
- Respuesta:
{ "message": "Hello world" }
Si el servidor está configurado para escribir registros para cada solicitud, los registros de servidor muestran que la llamada HTTP se ejecuta mediante un servicio gRPC. La transcodificación asigna la solicitud HTTP entrante a un mensaje de gRPC y, luego, convierte el mensaje de respuesta en 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
Anotación de métodos gRPC
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 el método HTTP y la ruta.
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {
option (google.api.http) = {
get: "/v1/greeter/{name}"
};
}
}
El ejemplo de procedimiento:
- Define un servicio
Greeter
con un métodoSayHello
. El método tiene una regla HTTP especificada con el nombregoogle.api.http
. - El método es accesible con solicitudes
GET
y la ruta/v1/greeter/{name}
. - El campo
name
del mensaje de solicitud está enlazado a un parámetro de ruta.
Hay muchas opciones disponibles para personalizar cómo un método gRPC se enlaza a una API RESTful. Para obtener más información sobre cómo anotar métodos gRPC y personalizar JSON, consulta Configuración de HTTP y JSON para la transcodificación de JSON de gRPC.
Métodos de streaming
El gRPC tradicional a través de HTTP/2 admite el streaming en todas las direcciones. La transcodificación se limita solo al streaming del servidor. No se admiten métodos de streaming de cliente ni de streaming bidireccional.
Los métodos de streaming de servidor usan JSON delimitado por líneas. Cada mensaje escrito mediante WriteAsync
se serializa a JSON y va seguido de una nueva línea.
El siguiente método de streaming de servidor escribe tres mensajes:
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));
}
}
El cliente recibe tres objetos JSON delimitados por líneas:
{"Text":"Message 1"}
{"Text":"Message 2"}
{"Text":"Message 3"}
Ten en cuenta que la configuración de WriteIndented
JSON no se aplica a los métodos de streaming de servidor. La impresión con sangría agrega nuevas líneas y espacios en blanco a JSON, que no se pueden usar con JSON delimitado por líneas.
Vea o descargue un ejemplo de aplicación de transcodificación y streaming de gPRC para ASP.NET Core.
Protocolo HTTP
La plantilla de servicio gRPC de ASP.NET Core, incluida en el SDK de .NET, crea una aplicación que solo está configurada para HTTP/2. HTTP/2 es un buen valor predeterminado cuando una aplicación solo admite gRPC tradicional a través de HTTP/2. Sin embargo, la transcodificación funciona con HTTP/1.1 y HTTP/2. Algunas plataformas, como UWP o Unity, no pueden usar HTTP/2. Para admitir todas las aplicaciones cliente, configure el servidor para habilitar HTTP/1.1 y HTTP/2.
Actualice el protocolo predeterminado en appsettings.json
:
{
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1AndHttp2"
}
}
}
Como alternativa, configure los puntos de conexión de Kestrel en el código de inicio.
La habilitación de HTTP/1.1 y HTTP/2 en el mismo puerto requiere TLS para la negociación de protocolos. Para obtener más información sobre cómo configurar protocolos HTTP en una aplicación gRPC, consulte Negociación del protocolo gRPC de ASP.NET Core.
Transcodificación JSON de gRPC frente a gRPC-Web
Tanto la transcodificación como gRPC-Web permiten llamar a servicios gRPC desde un explorador, aunque de manera diferente:
- gRPC-Web permite a las aplicaciones de explorador llamar a servicios gRPC desde el explorador con el cliente gRPC-Web y Protobuf. gRPC-Web requiere que la aplicación de explorador genere un cliente gRPC y tiene la ventaja de que envía mensajes de Protobuf pequeños y rápidos.
- La transcodificación permite a las aplicaciones de explorador llamar a servicios gRPC como si fueran API RESTful con JSON. No es necesario que la aplicación de explorador genere un cliente gRPC o que disponga de información sobre gRPC.
Se puede llamar al servicio Greeter
anterior mediante las API de JavaScript del explorador:
var name = nameInput.value;
fetch('/v1/greeter/' + name)
.then((response) => response.json())
.then((result) => {
console.log(result.message);
// Hello world
});
grpc-gateway
grpc-gateway es otra tecnología para crear API JSON de RESTful desde servicios gRPC. Usa las mismas anotaciones .proto
para asignar conceptos HTTP a servicios gRPC.
grpc-gateway utiliza la generación de código para crear un servidor proxy inverso. El proxy inverso traduce las llamadas RESTful a gRPC+Protobuf y envía las llamadas a través de HTTP/2 al servicio gRPC. La ventaja de este enfoque es que el servicio gRPC no conoce las API JSON de RESTful. Cualquier servidor gRPC puede usar grpc-gateway.
Mientras tanto, la transcodificación JSON de gRPC se ejecuta dentro de una aplicación de ASP.NET Core. Deserializa JSON en mensajes protobuf y, a continuación, invoca directamente el servicio gRPC. La transcodificación en ASP.NET Core ofrece ventajas a los desarrolladores de aplicaciones de .NET:
- Menos complejo: tanto los servicios gRPC como la API JSON RESTful asignada se ejecutan fuera de una aplicación de ASP.NET Core.
- Mejor rendimiento: la transcodificación deserializa JSON en mensajes Protobuf e invoca directamente el servicio gRPC. Hay importantes ventajas de rendimiento al hacer esto en proceso frente a realizar una nueva llamada gRPC a otro servidor.
- Menor costo: menos servidores dan lugar a una factura de hospedaje mensual más reducida.
Para obtener información sobre la instalación y el uso de grpc-gateway, consulte el archivo LÉAME de grpc-gateway.