gRPC JSON轉碼 gRPC JSON 轉碼允許瀏覽器應用調用 gRPC 服務,就像它們是使用 JSON 的 RESTful API 一樣。 瀏覽器應用不需要生成 gRPC 客戶端或瞭解 gRPC 的任何信息。 通過使用 HTTP 元數據註釋 .proto 文件,可從 gRPC 服務自動創建 R ...
gRPC JSON轉碼
gRPC JSON 轉碼允許瀏覽器應用調用 gRPC 服務,就像它們是使用 JSON 的 RESTful API 一樣。
- 瀏覽器應用不需要生成 gRPC 客戶端或瞭解 gRPC 的任何信息。
- 通過使用 HTTP 元數據註釋 .proto 文件,可從 gRPC 服務自動創建 RESTful API。
- 使應用可以同時支持 gRPC 和 JSON Web API,而無需重覆為兩者生成單獨的服務。
OpenAPI與gRPC Server
OpenAPI(以前稱為 Swagger)是一個與語言無關的規範,用於描述 API。 gRPC JSON 轉碼支持從轉碼 REST ful的 API 生成 OpenAPI。
實現Server端
通過VS新增GRPC Server,新增nuget包
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.49.0" />
<PackageReference Include="Microsoft.AspNetCore.Grpc.JsonTranscoding" Version="7.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Grpc.Swagger" Version="0.3.0" />
</ItemGroup>
為api生成用於OpenAPI的註釋XML文件,在Server.csproj文件中新增以下配置
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Server的Program.cs中,開啟JSON轉碼與Swagger
var builder = WebApplication.CreateBuilder(args);
// 開啟JSON轉碼
builder.Services.AddGrpc().AddJsonTranscoding();
// 配置Swagger
builder.Services.AddGrpcSwagger();
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "gRPC transcoding", Version = "v1" });
var filePath = Path.Combine(System.AppContext.BaseDirectory, "GrpcService4.xml");
c.IncludeXmlComments(filePath);
c.IncludeGrpcXmlComments(filePath, includeControllerXmlComments: true);
});
var app = builder.Build();
//開啟Swagger
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
app.MapGrpcService<GreeterService>();
app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
app.Run();
下載GRPC JSON轉碼依賴的proto文件
https://github.com/dotnet/aspnetcore/blob/main/src/Grpc/JsonTranscoding/test/testassets/Sandbox/google/api/http.proto
https://github.com/dotnet/aspnetcore/blob/main/src/Grpc/JsonTranscoding/test/testassets/Sandbox/google/api/annotations.proto
並將文件放到項目的google/api/文件夾中。
修改greet.proto文件,通過option開啟http選項,以一個get方法和一個post方法舉例
syntax = "proto3";
import "google/api/annotations.proto";
option csharp_namespace = "GrpcService4";
package greet;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply){
option (google.api.http) = {
get: "/v1/greeter/{name}"
};
};
// Sends a greeting
rpc SayHelloPost (HelloRequestPost) returns (HelloReply){
option (google.api.http) = {
post: "/v1/greeter/post",
body:"data"
};
};
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The request message containing the user's name.
message HelloRequestPost {
HelloRequestPostData data = 1;
}
message HelloRequestPostData{
string name = 1;
string gender = 2;
}
// The response message containing the greetings.
message HelloReply {
string message = 1;
}
然後實現Server
using Grpc.Core;
using GrpcService4;
namespace GrpcService4.Services
{
public class GreeterService : Greeter.GreeterBase
{
private readonly ILogger<GreeterService> _logger;
public GreeterService(ILogger<GreeterService> logger)
{
_logger = logger;
}
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
public override Task<HelloReply> SayHelloPost(HelloRequestPost request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Data.Name
});
}
}
}
至此server的json轉碼開啟完成,運行服務,訪問swagger,即可嘗試http方式請求
在支持http方式的請求的情況下,同時支持grpc請求。
實現Client端
新增控制台項目,添加以下nuget
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.21.9" />
<PackageReference Include="Grpc.Net.Client" Version="2.49.0" />
<PackageReference Include="Microsoft.AspNetCore.Grpc.JsonTranscoding" Version="7.0.0" />
<PackageReference Include="Grpc.Tools" Version="2.50.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
包含與server端相同的proto文件
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Client" />
</ItemGroup>
嘗試請求Server
static async Task Main(string[] args)
{
using var channel = GrpcChannel.ForAddress("https://localhost:7167");
var client = new Greeter.GreeterClient(channel);
var reply = await client.SayHelloAsync(new HelloRequest { Name = "GreeterClient" });
Console.WriteLine("Greeting: " + reply.Message);
var replyPost = await client.SayHelloPostAsync(new HelloRequestPost { Data = new HelloRequestPostData { Name = "111" } });
Console.WriteLine("Greeting: " + replyPost.Message);
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
source code: https://github.com/cysnet/grpc-json-transcoding