Транскодирование JSON gRPC в ASP.NET Core
Примечание.
Это не последняя версия этой статьи. В текущем выпуске см . версию .NET 8 этой статьи.
Предупреждение
Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в статье о политике поддержки .NET и .NET Core. В текущем выпуске см . версию .NET 8 этой статьи.
Внимание
Эта информация относится к предварительному выпуску продукта, который может быть существенно изменен до его коммерческого выпуска. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
В текущем выпуске см . версию .NET 8 этой статьи.
Автор: Джеймс Ньютон-Кинг (James Newton-King)
gRPC — это высокопроизводительная платформа удаленного вызова процедур (RPC). gRPC использует HTTP/2, потоковую передачу, Protobuf и контракты сообщений для создания высокопроизводительных служб в реальном времени.
Одним из ограничений gRPC является то, что не каждая платформа может использовать ее. Браузеры не полностью поддерживают HTTP/2, поэтому API REST и JSON являются основными способами для передачи данных в браузерные приложения. Несмотря на преимущества, которые gRPC приносит, REST API и JSON имеют важное место в современных приложениях. Создание веб-API gRPC и JSON добавляет нежелательные затраты на разработку приложений.
В этом документе рассматривается создание веб-API JSON с помощью служб gRPC.
Обзор
Перекодирование gRPC JSON — это расширение для ASP.NET Core, которое создает API JSON RESTful для служб gRPC. Настроенное перекодирование позволяет приложениям вызывать службы gRPC, используя следующие привычные понятия HTTP:
- HTTP-команды
- привязку параметра URL-адреса;
- запросы и ответы JSON.
gRPC по-прежнему можно использовать для вызова служб.
Примечание.
Транскодирование JSON gRPC заменяет API HTTP gRPC, альтернативное экспериментальное расширение.
Использование
Добавьте ссылку на пакет для
Microsoft.AspNetCore.Grpc.JsonTranscoding
.Зарегистрируйте перекодирование в коде запуска сервера, добавив
AddJsonTranscoding
: вProgram.cs
файле изменитсяbuilder.Services.AddGrpc();
наbuilder.Services.AddGrpc().AddJsonTranscoding();
.Добавьте
<IncludeHttpRuleProtos>true</IncludeHttpRuleProtos>
в группу свойств в файле проекта (.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>
Заметьте методы gRPC в
.proto
файлах с привязками и маршрутами 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; }
Теперь метод SayHello
gRPC можно вызывать как gRPC и веб-API JSON:
- Запрос:
GET /v1/greeter/world
- Ответ:
{ "message": "Hello world" }
Если сервер настроен на запись журналов для каждого запроса, журналы сервера показывают, что служба gRPC выполняет http-вызов. Перекодирование сопоставляет входящий HTTP-запрос с сообщением gRPC и преобразует ответное сообщение в 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
Аннотировать методы gRPC
Методы gRPC должны быть аннотированы с помощью правила HTTP, прежде чем они поддерживают перекодирование. Правило HTTP содержит сведения о том, как вызвать метод gRPC, например метод HTTP и маршрут.
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {
option (google.api.http) = {
get: "/v1/greeter/{name}"
};
}
}
Пример процедуры:
- Определяет
Greeter
службу с методомSayHello
. Метод имеет правило HTTP, указанное с помощью имениgoogle.api.http
. - Метод доступен с запросами
GET
и маршрутом/v1/greeter/{name}
. name
Поле сообщения запроса привязано к параметру маршрута.
Многие варианты доступны для настройки привязки метода gRPC к API RESTful. Дополнительные сведения о аннотации методов gRPC и настройке JSON см. в разделе "Настройка HTTP и JSON для транскодирования JSON gRPC".
Методы потоковой передачи
Традиционный API gRPC по HTTP/2 поддерживает потоковую передачу во всех направлениях. Перекодирование предназначено только для серверной потоковой передачи. Методы клиентской и двунаправленной потоковой передачи не поддерживаются.
Методы потоковой передачи сервера используют json с разделителями строк. Каждое сообщение, написанное с помощью WriteAsync
, сериализуется в ФОРМАТЕ JSON и следует новая строка.
Следующий метод серверной потоковой передачи записывает три сообщения:
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));
}
}
Клиент получает три объекта JSON с разделителями строк:
{"Text":"Message 1"}
{"Text":"Message 2"}
{"Text":"Message 3"}
Обратите внимание, что WriteIndented
параметр JSON не применяется к методам потоковой передачи сервера. Красивая печать добавляет новые строки и пробелы в JSON, которые нельзя использовать с разделителями строк JSON.
Просмотр или скачивание примера приложения ASP.NET Core gPRC для перекодирования и потоковой передачи.
Протокол HTTP
Шаблон службы ASP.NET Core gRPC, включенный в пакет SDK для .NET, создает приложение, настроенное только для HTTP/2. HTTP/2 является хорошим по умолчанию, если приложение поддерживает только традиционные gRPC по протоколу HTTP/2. Однако перекодирование работает как с HTTP/1.1, так и с HTTP/2. Некоторые платформы, например UWP или Unity, не могут использовать HTTP/2. Чтобы обеспечить поддержку всех клиентских приложений, настройте сервер для включения HTTP/1.1 и HTTP/2.
Обновите протокол умолчанию в файле appsettings.json
:
{
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1AndHttp2"
}
}
}
Как вариант, вы можете настроить конечные точки Kestrel в коде запуска.
Чтобы включить HTTP/1.1 и HTTP/2 на одном порте, требуется TLS для согласования протокола. Дополнительные сведения о настройке протоколов HTTP в приложении gRPC см. в разделе Согласование протокола gRPC в ASP.NET Core.
Транскодирование json gRPC и gRPC-Web
Как перекодирование, так и gRPC-Web позволяют вызывать службы gRPC из браузера. Однако способы, которыми они это делают, отличаются.
- gRPC-Web позволяет браузерным приложениям вызывать службы gRPC из браузера с помощью клиента gRPC-Web и Protobuf. gRPC-Web требует, чтобы приложение браузера создало клиент gRPC и имеет преимущество отправки небольших, быстрых сообщений Protobuf.
- Транскодирование позволяет приложениям браузера вызывать службы gRPC, как если бы они были API RESTful с JSON. Браузерному приложению не нужно создавать клиент gRPC и не нужно ничего знать о gRPC.
Предыдущую службу Greeter
можно вызывать с помощью API JavaScript браузера:
var name = nameInput.value;
fetch('/v1/greeter/' + name)
.then((response) => response.json())
.then((result) => {
console.log(result.message);
// Hello world
});
grpc-gateway
grpc-gateway — еще одна технология создания API RESTful JSON из служб gRPC. В нем используются те же .proto
заметки для сопоставления концепций HTTP с службами gRPC.
grpc-gateway использует генерирование кода для создания обратного прокси-сервера. Обратный прокси-сервер преобразует вызовы RESTful в gRPC+Protobuf и отправляет вызовы по протоколу HTTP/2 в службу gRPC. Преимущество этого подхода заключается в том, что служба gRPC не знает об API JSON RESTful. Любой сервер gRPC может использовать grpc-gateway.
Между тем перекодирование JSON gRPC выполняется в приложении ASP.NET Core. При этом JSON десериализируется в сообщения Protobuf, а затем вызывается служба gRPC напрямую. Перекодирование в ASP.NET Core предоставляет следующие преимущества для разработчиков приложений .NET:
- Снижение сложности: и службы gRPC и сопоставленные API JSON RESTful выполняются из одного приложения ASP.NET Core.
- Улучшенная производительность: транскодирование десериализирует json в сообщения Protobuf и вызывает службу gRPC напрямую. Существует значительное преимущество, связанное с производительностью, при выполнении этого внутрипроцессного вызова, а не при вызове gRPC к другому серверу.
- Снижение стоимости: меньшее количество серверов приводит к уменьшению ежемесячного счета за размещение.
Сведения об установке и использовании grpc-gateway см. в файле сведений для grpc-gateway.
Дополнительные ресурсы
gRPC — это высокопроизводительная платформа удаленного вызова процедур (RPC). gRPC использует HTTP/2, потоковую передачу, Protobuf и контракты сообщений для создания высокопроизводительных служб в реальном времени.
Одним из ограничений gRPC является то, что не каждая платформа может использовать ее. Браузеры не полностью поддерживают HTTP/2, поэтому API REST и JSON являются основными способами для передачи данных в браузерные приложения. Несмотря на преимущества, которые gRPC приносит, REST API и JSON имеют важное место в современных приложениях. Создание веб-API gRPC и JSON добавляет нежелательные затраты на разработку приложений.
В этом документе рассматривается создание веб-API JSON с помощью служб gRPC.
Обзор
Перекодирование gRPC JSON — это расширение для ASP.NET Core, которое создает API JSON RESTful для служб gRPC. Настроенное перекодирование позволяет приложениям вызывать службы gRPC, используя следующие привычные понятия HTTP:
- HTTP-команды
- привязку параметра URL-адреса;
- запросы и ответы JSON.
gRPC по-прежнему можно использовать для вызова служб.
Примечание.
Транскодирование JSON gRPC заменяет API HTTP gRPC, альтернативное экспериментальное расширение.
Использование
- Добавьте ссылку на пакет для
Microsoft.AspNetCore.Grpc.JsonTranscoding
. - Зарегистрируйте перекодирование в коде запуска сервера, добавив
AddJsonTranscoding
: вProgram.cs
файле изменитсяbuilder.Services.AddGrpc();
наbuilder.Services.AddGrpc().AddJsonTranscoding();
. - Создайте структуру
/google/api
каталогов в каталоге проекта, который содержит.csproj
файл. - Добавьте
google/api/http.proto
иgoogle/api/annotations.proto
файлы в/google/api
каталог. - Заметьте методы gRPC в
.proto
файлах с привязками и маршрутами 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;
}
Теперь метод SayHello
gRPC можно вызывать как gRPC и веб-API JSON:
- Запрос:
GET /v1/greeter/world
- Ответ:
{ "message": "Hello world" }
Если сервер настроен на запись журналов для каждого запроса, журналы сервера показывают, что служба gRPC выполняет http-вызов. Перекодирование сопоставляет входящий HTTP-запрос с сообщением gRPC и преобразует ответное сообщение в 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
Аннотировать методы gRPC
Методы gRPC должны быть аннотированы с помощью правила HTTP, прежде чем они поддерживают перекодирование. Правило HTTP содержит сведения о том, как вызвать метод gRPC, например метод HTTP и маршрут.
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {
option (google.api.http) = {
get: "/v1/greeter/{name}"
};
}
}
Пример процедуры:
- Определяет
Greeter
службу с методомSayHello
. Метод имеет правило HTTP, указанное с помощью имениgoogle.api.http
. - Метод доступен с запросами
GET
и маршрутом/v1/greeter/{name}
. name
Поле сообщения запроса привязано к параметру маршрута.
Многие варианты доступны для настройки привязки метода gRPC к API RESTful. Дополнительные сведения о аннотации методов gRPC и настройке JSON см. в разделе "Настройка HTTP и JSON для транскодирования JSON gRPC".
Методы потоковой передачи
Традиционный API gRPC по HTTP/2 поддерживает потоковую передачу во всех направлениях. Перекодирование предназначено только для серверной потоковой передачи. Методы клиентской и двунаправленной потоковой передачи не поддерживаются.
Методы потоковой передачи сервера используют json с разделителями строк. Каждое сообщение, написанное с помощью WriteAsync
, сериализуется в ФОРМАТЕ JSON и следует новая строка.
Следующий метод серверной потоковой передачи записывает три сообщения:
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));
}
}
Клиент получает три объекта JSON с разделителями строк:
{"Text":"Message 1"}
{"Text":"Message 2"}
{"Text":"Message 3"}
Обратите внимание, что WriteIndented
параметр JSON не применяется к методам потоковой передачи сервера. Красивая печать добавляет новые строки и пробелы в JSON, которые нельзя использовать с разделителями строк JSON.
Просмотр или скачивание примера приложения ASP.NET Core gPRC для перекодирования и потоковой передачи.
Протокол HTTP
Шаблон службы ASP.NET Core gRPC, включенный в пакет SDK для .NET, создает приложение, настроенное только для HTTP/2. HTTP/2 является хорошим по умолчанию, если приложение поддерживает только традиционные gRPC по протоколу HTTP/2. Однако перекодирование работает как с HTTP/1.1, так и с HTTP/2. Некоторые платформы, например UWP или Unity, не могут использовать HTTP/2. Чтобы обеспечить поддержку всех клиентских приложений, настройте сервер для включения HTTP/1.1 и HTTP/2.
Обновите протокол умолчанию в файле appsettings.json
:
{
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1AndHttp2"
}
}
}
Как вариант, вы можете настроить конечные точки Kestrel в коде запуска.
Чтобы включить HTTP/1.1 и HTTP/2 на одном порте, требуется TLS для согласования протокола. Дополнительные сведения о настройке протоколов HTTP в приложении gRPC см. в разделе Согласование протокола gRPC в ASP.NET Core.
Транскодирование json gRPC и gRPC-Web
Как перекодирование, так и gRPC-Web позволяют вызывать службы gRPC из браузера. Однако способы, которыми они это делают, отличаются.
- gRPC-Web позволяет браузерным приложениям вызывать службы gRPC из браузера с помощью клиента gRPC-Web и Protobuf. gRPC-Web требует, чтобы приложение браузера создало клиент gRPC и имеет преимущество отправки небольших, быстрых сообщений Protobuf.
- Транскодирование позволяет приложениям браузера вызывать службы gRPC, как если бы они были API RESTful с JSON. Браузерному приложению не нужно создавать клиент gRPC и не нужно ничего знать о gRPC.
Предыдущую службу Greeter
можно вызывать с помощью API JavaScript браузера:
var name = nameInput.value;
fetch('/v1/greeter/' + name)
.then((response) => response.json())
.then((result) => {
console.log(result.message);
// Hello world
});
grpc-gateway
grpc-gateway — еще одна технология создания API RESTful JSON из служб gRPC. В нем используются те же .proto
заметки для сопоставления концепций HTTP с службами gRPC.
grpc-gateway использует генерирование кода для создания обратного прокси-сервера. Обратный прокси-сервер преобразует вызовы RESTful в gRPC+Protobuf и отправляет вызовы по протоколу HTTP/2 в службу gRPC. Преимущество этого подхода заключается в том, что служба gRPC не знает об API JSON RESTful. Любой сервер gRPC может использовать grpc-gateway.
Между тем перекодирование JSON gRPC выполняется в приложении ASP.NET Core. При этом JSON десериализируется в сообщения Protobuf, а затем вызывается служба gRPC напрямую. Перекодирование в ASP.NET Core предоставляет следующие преимущества для разработчиков приложений .NET:
- Снижение сложности: и службы gRPC и сопоставленные API JSON RESTful выполняются из одного приложения ASP.NET Core.
- Улучшенная производительность: транскодирование десериализирует json в сообщения Protobuf и вызывает службу gRPC напрямую. Существует значительное преимущество, связанное с производительностью, при выполнении этого внутрипроцессного вызова, а не при вызове gRPC к другому серверу.
- Снижение стоимости: меньшее количество серверов приводит к уменьшению ежемесячного счета за размещение.
Сведения об установке и использовании grpc-gateway см. в файле сведений для grpc-gateway.
Дополнительные ресурсы
ASP.NET Core