ASP.NET Core: Chuyển mã JSON gRPC trong ASP.NET Core
Trong bài viết này
- Tổng quan
- Cách sử dụng
- Giao thức HTTP
- Chuyển mã JSON gRPC so với gRPC-Web
- Cổng grpc
- Tài nguyên bổ sung
gRPC là framework Gọi thủ tục từ xa (RPC) hiệu suất cao. gRPC sử dụng các hợp đồng HTTP/2, truyền phát, Protobuf và message để tạo ra các dịch vụ thời gian thực, hiệu suất cao.
Một hạn chế của gRPC là không phải nền tảng nào cũng có thể sử dụng nó. Các trình duyệt không hỗ trợ đầy đủ HTTP/2, khiến API REST và JSON trở thành cách chính để đưa dữ liệu vào ứng dụng trình duyệt. Bất chấp những lợi ích mà gRPC mang lại, API REST và JSON vẫn có một vị trí quan trọng trong các ứng dụng hiện đại. Việc xây dựng API Web gRPC và JSON sẽ bổ sung thêm chi phí không mong muốn cho quá trình phát triển ứng dụng.
Bài viết này thảo luận cách tạo API Web JSON bằng dịch vụ gRPC.
Tổng quan
Chuyển mã (Transcoding) JSON gRPC là một tiện ích mở rộng cho ASP.NET Core giúp tạo API RESTful JSON cho các dịch vụ gRPC. Sau khi được định cấu hình, chuyển mã cho phép ứng dụng gọi các dịch vụ gRPC bằng các khái niệm HTTP quen thuộc:
- HTTP Verb
- Ràng buộc tham số URL
- Request/Response JSON
gRPC vẫn có thể được sử dụng để gọi các dịch vụ.
Ghi chú
Chuyển mã JSON gRPC thay thế cho API HTTP gRPC, một tiện ích mở rộng thử nghiệm thay thế.
Cách sử dụng
- Thêm tham chiếu gói vào Microsoft.AspNetCore.Grpc.JsonTranscoding.
- Đăng ký chuyển mã trong mã khởi động máy chủ bằng cách thêm
AddJsonTranscoding
: Trong fileProgram.cs
, thay đổibuilder.Services.AddGrpc();
thànhbuilder.Services.AddGrpc().AddJsonTranscoding();
. - Tạo cấu trúc thư mục
/google/api
trong thư mục dự án chứa file.csproj
. - Thêm các file google/api/http.proto và google/api/annotations.proto vào thư mục
/google/api
. - Ghi chú các phương thức gRPC trong file
.proto
của bạn bằng các liên kết và định tuyến HTTP:
syntax = "proto3";
option csharp_namespace = "GrpcServiceTranscoding";
import "google/api/annotations.proto";
package greet;
// Định nghĩa dịch vụ greeting.
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {
option (google.api.http) = {
get: "/v1/greeter/{name}"
};
}
}
// Request message chứa tên người dùng.
message HelloRequest {
string name = 1;
}
// Response message chứa lời chào.
message HelloReply {
string message = 1;
}
Phương thức gRPC SayHello
lúc này có thể được gọi dưới dạng gRPC và dưới dạng API Web JSON:
- Request:
GET /v1/greeter/world
- Response:
{ "message": "Hello world" }
Nếu máy chủ được định cấu hình để ghi nhật ký cho từng yêu cầu thì nhật ký máy chủ sẽ hiển thị rằng dịch vụ gRPC thực hiện lệnh gọi HTTP. Chuyển mã ánh xạ request HTTP đến vào message gRPC và chuyển đổi message phản hồi thành 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
Ghi chú (Annotate) các phương thức gRPC
Các phương thức gRPC phải được ghi chú bằng quy tắc HTTP trước khi chúng hỗ trợ chuyển mã. Quy tắc HTTP bao gồm thông tin về cách gọi phương thức gRPC, chẳng hạn như phương thức và định tuyến HTTP.
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {
option (google.api.http) = {
get: "/v1/greeter/{name}"
};
}
}
Ví dụ trên:
- Định nghĩa một dịch vụ
Greeter
với một phương thứcSayHello
. Phương thức này có quy tắc HTTP được chỉ định bằng têngoogle.api.http
. - Phương thức này có thể truy cập được bằng các request
GET
và định tuyến/v1/greeter/{name}
. - Trường
name
trên message request được liên kết với tham số route.
Có nhiều tùy chọn để tùy chỉnh cách phương thức gRPC liên kết với API RESTful. Để biết thêm thông tin về ghi chú các phương thức gRPC và tùy chỉnh JSON, hãy xem Định cấu hình HTTP và JSON để chuyển mã JSON gRPC.
Phương thức truyền phát
gRPC truyền thống qua HTTP/2 hỗ trợ truyền phát theo mọi hướng. Việc chuyển mã chỉ giới hạn ở việc truyền phát máy chủ. Phương thức truyền phát máy khách và truyền phát hai chiều không được hỗ trợ.
Phương thức truyền phát máy chủ sử dụng JSON được phân cách bằng dòng. Mỗi message được viết bằng cách sử dụng WriteAsync
đều được tuần tự hóa thành JSON và theo sau là một dòng mới.
Phương thức truyền phát máy chủ sau viết ba thông báo:
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));
}
}
Máy khách nhận được ba đối tượng JSON được phân cách bằng dòng:
{"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 truyền phát máy chủ. Bản in đẹp sẽ thêm các dòng và khoảng trắng mới vào JSON, không thể sử dụng được với JSON được phân cách bằng dòng.
Xem hoặc tải xuống mẫu ứng dụng truyền phát và chuyển mã gPRC của ASP.NET Core.
Giao thức HTTP
Mẫu dịch vụ gRPC ASP.NET Core có trong .NET SDK tạo ra một ứng dụng chỉ được định cấu hình cho HTTP/2. HTTP/2 là một mặc định phù hợp khi một ứng dụng chỉ hỗ trợ gRPC truyền thống qua HTTP/2. Tuy nhiên, tính năng chuyển mã 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 khách, hãy định cấu hình máy chủ để bật HTTP/1.1 và HTTP/2.
Cập nhật giao thức mặc định trong appsettings.json
:
{
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1AndHttp2"
}
}
}
Ngoài ra, hãy định cấu hình điểm cuối Kestrel trong code startup.
Việc bật HTTP/1.1 và HTTP/2 trên cùng một cổng yêu cầu TLS để đàm phán giao thức. Để biết thêm thông tin về cách định cấu hình giao thức HTTP trong ứng dụng gRPC, hãy xem Đàm phán giao thức gRPC của ASP.NET Core.
Chuyển mã JSON gRPC so với gRPC-Web
Cả chuyển mã và gRPC-Web đều cho phép gọi các dịch vụ gRPC từ trình duyệt. Tuy nhiên, cách thực hiện của chúng là khác nhau:
- gRPC-Web cho phép các ứng dụng trình duyệt gọi các dịch vụ gRPC từ trình duyệt bằng ứng dụng khách gRPC-Web và Protobuf. gRPC-Web yêu cầu ứng dụng trình duyệt tạo ứng dụng khách gRPC và có lợi thế là gửi các message Protobuf nhỏ, nhanh.
- Chuyển mã cho phép các ứng dụng trình duyệt gọi các dịch vụ gRPC như thể chúng là các API RESTful có JSON. Ứng dụng trình duyệt không cần tạo ứng dụng khách gRPC hoặc biết bất kỳ điều gì về gRPC.
Dịch vụ Greeter
ở trên có thể được gọi bằng API JavaScript của trình duyệt:
var name = nameInput.value;
fetch('/v1/greeter/' + name)
.then((response) => response.json())
.then((result) => {
console.log(result.message);
// Hello world
});
Cổng grpc
Cổng grpc (grpc-gateway) là một công nghệ khác để tạo API RESTful JSON từ các dịch vụ gRPC. Nó sử dụng các ghi chú .proto
tương tự để ánh xạ các khái niệm HTTP tới các dịch vụ gRPC.
grpc-gateway sử dụng việc tạo mã để tạo máy chủ proxy ngược. Proxy ngược chuyển các lời gọi RESTful thành gRPC+Protobuf và gửi các lời gọi qua HTTP/2 tới dịch vụ gRPC. Lợi ích của phương pháp này là dịch vụ gRPC không biết về API RESTful JSON. Bất kỳ máy chủ gRPC nào cũng có thể sử dụng grpc-gateway.
Trong khi đó, chuyển mã JSON gRPC chạy bên trong ứng dụng ASP.NET Core. Nó giải tuần tự hóa JSON thành các message Protobuf, sau đó gọi trực tiếp dịch vụ gRPC. Chuyển mã trong ASP.NET Core mang lại lợi ích cho các nhà phát triển ứng dụng .NET:
- Ít phức tạp hơn: Cả dịch vụ gRPC và API RESTful JSON được ánh xạ đều hết một ứng dụng ASP.NET Core.
- Hiệu suất tốt hơn: Chuyển mã sẽ giải tuần tự hóa các message JSON thành Protobuf và gọi trực tiếp dịch vụ gRPC. Có những lợi ích đáng kể về hiệu suất khi thực hiện việc này trong quá trình so với việc thực hiện lệnh gọi gRPC mới tới một máy chủ khác.
- Chi phí thấp hơn: Ít máy chủ hơn dẫn đến hóa đơn lưu trữ hàng tháng nhỏ hơn.
Để cài đặt và sử dụng grpc-gateway, hãy xem grpc-gateway README.
Tài nguyên bổ sung
- Định cấu hình HTTP và JSON để chuyển mã JSON gRPC cho các ứng dụng ASP.NET Core
- Sử dụng OpenAPI với các ứng dụng ASP.NET Core chuyển mã JSON gRPC
- Sử dụng gRPC trong ứng dụng trình duyệt
- gRPC-Web trong ứng dụng gRPC ASP.NET Core