Nguon: Microsoft Learn · .NET 8.0

gRPC JSON transcoding trong các ứng dụng ASP.NET Core gRPC

Nguồn: gRPC JSON transcoding in ASP.NET Core gRPC apps

gRPC là một Remote Procedure Call (RPC - Lời gọi thủ tục từ xa) framework hiệu năng cao. gRPC sử dụng HTTP/2, streaming (luồng dữ liệu), Protobuf và các hợp đồng message để tạo ra các service thời gian thực với hiệu năng cao.

Một hạn chế của gRPC là không phải mọi nền tảng đều có thể sử dụng nó. Các trình duyệt không hỗ trợ đầy đủ HTTP/2, khiến REST API và JSON trở thành cách chính để truyền dữ liệu vào các ứng dụng trình duyệt. Mặc dù có những lợi ích mà gRPC mang lại, REST API và JSON vẫn có vị trí quan trọng trong các ứng dụng hiện đại. Xây dựng cả gRPC lẫn JSON Web API tạo thêm overhead (chi phí) không mong muốn cho việc phát triển ứng dụng.

Tài liệu này thảo luận về cách tạo JSON Web API bằng cách sử dụng gRPC services.

Tổng quan

gRPC JSON transcoding (chuyển mã gRPC JSON) là một extension cho ASP.NET Core tạo ra RESTful JSON API từ gRPC services. Sau khi được cấu hình, transcoding cho phép các ứng dụng gọi gRPC services với các khái niệm HTTP quen thuộc:

gRPC vẫn có thể được sử dụng để gọi services.

Lưu ý: gRPC JSON transcoding thay thế gRPC HTTP API, một extension thử nghiệm thay thế.

Cách sử dụng

  1. Thêm tham chiếu package đến Microsoft.AspNetCore.Grpc.JsonTranscoding.
  2. Đăng ký transcoding trong startup code của server bằng cách thêm AddJsonTranscoding: Trong file Program.cs, thay đổi builder.Services.AddGrpc(); thành builder.Services.AddGrpc().AddJsonTranscoding();.
  3. Thêm <IncludeHttpRuleProtos>true</IncludeHttpRuleProtos> vào property group trong project file (.csproj):

```json <Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup> <TargetFramework>net8.0</TargetFramework> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings> <InvariantGlobalization>true</InvariantGlobalization> <IncludeHttpRuleProtos>true</IncludeHttpRuleProtos> </PropertyGroup> ```

  1. Chú thích các gRPC method trong các file .proto với HTTP bindings và routes:

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

gRPC method SayHello giờ có thể được gọi như gRPC và như một JSON Web API:

Nếu server được cấu hình để ghi log cho mỗi request, server logs sẽ cho thấy rằng một gRPC service thực thi lời gọi HTTP. Transcoding ánh xạ HTTP request đến vào một gRPC message và chuyển đổi response message sang JSON.

text
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

Chú thích các gRPC method

Các gRPC method phải được chú thích với một HTTP rule trước khi chúng hỗ trợ transcoding. HTTP rule bao gồm thông tin về cách gọi gRPC method, chẳng hạn như HTTP method và route.

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

Ví dụ trên:

Có nhiều tùy chọn để tùy chỉnh cách một gRPC method ràng buộc với RESTful API. Để biết thêm thông tin về chú thích gRPC method và tùy chỉnh JSON, xem Configure HTTP and JSON for gRPC JSON transcoding.

Các phương thức streaming (luồng dữ liệu)

gRPC truyền thống qua HTTP/2 hỗ trợ streaming theo tất cả các hướng. Transcoding chỉ giới hạn ở server streaming. Các phương thức client streaming và bidirectional streaming không được hỗ trợ.

Các phương thức server streaming sử dụng line-delimited JSON (JSON được phân tách bằng dòng mới). Mỗi message được ghi bằng WriteAsync được serialized sang JSON và theo sau bởi một dòng mới.

Phương thức server streaming sau ghi ba message:

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

Client nhận được ba đối tượng JSON được phân tách bằng dòng mới:

json
{"Text":"Message 1"}
{"Text":"Message 2"}
{"Text":"Message 3"}

Lưu ý rằng cài đặt JSON WriteIndented không áp dụng cho các phương thức server streaming. Pretty printing (in đẹp) thêm dòng mới và khoảng trắng vào JSON, không thể sử dụng với line-delimited JSON.

Xem hoặc tải xuống mẫu ứng dụng ASP.NET Core gPRC transcoding và streaming.

Giao thức HTTP

Template ASP.NET Core gRPC service, được bao gồm trong .NET SDK, tạo ứng dụng chỉ được cấu hình cho HTTP/2. HTTP/2 là mặc định tốt khi ứng dụng chỉ hỗ trợ gRPC truyền thống qua HTTP/2. Tuy nhiên, transcoding hoạt động với cả HTTP/1.1 và HTTP/2. Một số nền tảng, chẳng hạn như UWP hoặc Unity, không thể sử dụng HTTP/2. Để hỗ trợ tất cả các ứng dụng client, hãy cấu hình server để bật HTTP/1.1 và HTTP/2.

Cập nhật giao thức mặc định trong appsettings.json:

json
{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1AndHttp2"
    }
  }
}

Ngoài ra, cấu hình Kestrel endpoints trong startup code.

Bật HTTP/1.1 và HTTP/2 trên cùng một cổng yêu cầu TLS để thương lượng giao thức. Để biết thêm thông tin về cấu hình giao thức HTTP trong ứng dụng gRPC, xem ASP.NET Core gRPC protocol negotiation.

gRPC JSON transcoding so với gRPC-Web

Cả transcoding và gRPC-Web đều cho phép gọi gRPC services từ trình duyệt. Tuy nhiên, cách mỗi loại thực hiện điều này là khác nhau:

Greeter service trước đó có thể được gọi bằng các JavaScript API trình duyệt:

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 là một công nghệ khác để tạo RESTful JSON API từ gRPC services. Nó sử dụng cùng các .proto annotation để ánh xạ các khái niệm HTTP đến gRPC services.

grpc-gateway sử dụng việc tạo code để tạo một reverse-proxy server. Reverse proxy dịch các lời gọi RESTful thành gRPC+Protobuf và gửi các lời gọi qua HTTP/2 đến gRPC service. Lợi ích của cách tiếp cận này là gRPC service không biết về các RESTful JSON API. Bất kỳ gRPC server nào cũng có thể sử dụng grpc-gateway.

Trong khi đó, gRPC JSON transcoding chạy bên trong ứng dụng ASP.NET Core. Nó deserialize JSON thành các Protobuf message, sau đó gọi trực tiếp gRPC service. Transcoding trong ASP.NET Core cung cấp các lợi thế cho các nhà phát triển ứng dụng .NET:

Để biết cài đặt và cách sử dụng grpc-gateway, xem grpc-gateway README.