目标
在一个网站内,用一套proto即提供gPRC 调用,又提供 Web API 调用。
实现方法
根据微软官方James Newton King(Newtonsoft.json 作者)的文章,.net7 里面提供了 JsonTranscoding 特性,只需要三步(翻译自链接中的文档):
- 第一步用vs2022创建一个 .net7的 gRPC service Create a gRPC client and service
- 第二步,添加nuget包
Microsoft.AspNetCore.Grpc.JsonTranscoding。在服务的
startup.cs 文件里添加一句services.AddGrpc().AddJsonTranscoding();
- 最后在 proto 文件里面加上
import "google/api/annotations.proto"; 要求将
annotations.proto 和 http.proto 两个文件下载放到你的proto文件所在文件夹下的google/api
子文件夹中。
另外,可以观看我翻译配音的 James Newton King 的专题讲座.NET Conf 2022: .NET7 gRPC 性能提升同时兼具Web API。
上手比划
主要是找不到 google/api 文件夹编译报错,确保在自己proto文件相同的文件夹下就行了,不用额外安装google的其他包,下面是我的文件夹结构:
在我自己定义的schedulerpc.proto文件中,加上了 import "google/api/annotations.proto";
syntax = "proto3";
import "common.proto";
import "google/protobuf/wrappers.proto";
import "google/api/annotations.proto";
option csharp_namespace = "Easy.Flownet.Services";
service ScheduleRPC {
rpc GetVariables (RequestName) returns (VariableInfoList){
option(google.api.http)={
get:"/schedule/{name}"
};
}
}
在gRPC服务里面进行了方法实现:
public class ScheduleService : ScheduleRPC.ScheduleRPCBase
{
public ScheduleService() : base()
{
}
public override Task<VariableInfoList> GetVariables(RequestName request, ServerCallContext context)
{
//实现代码
}
}
在startup.cs(或program.cs)中加上了
services.AddGrpc().AddJsonTranscoding();
并注册了ScheduleService 服务
endpoints.MapGrpcService<ScheduleService>();
添加 Swagger
跟着.NET Conf 2022: .NET7 gRPC 性能提升同时兼具Web API一步一步操作,首先在服务所在工程文件中添加两个包
<PackageReference Include="Microsoft.AspNetCore.Grpc.JsonTranscoding" Version="7.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Grpc.Swagger" Version="0.3.0" />
然后在startup.cs 或 program.cs 中添加代码
services.AddGrpcReflection();
services.AddGrpcSwagger();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title="My API", Version="v1"});
});
...
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
...
endpoints.MapGrpcReflectionService();
That's all you need.
运行
启动gRPC服务后,在浏览器中键入我在schedulerpc.proto文件中给GetVariables指定的url地址,http://localhost:5002/schedule/{name} 正确返回了json。
然后我立刻删除了单独创建的web api项目,也不用再为gRPC与web api之间的互操作烦恼了,因为都在一个项目里,是不是很爽啊?!感谢James Newton King!
后记:http 和 gRPC同时提供
我之前测试时都只单独试了gRPC或Web API,今天把他俩放到一块时发现gRPC 不能调用了,查了官方文档有这么一句话:
Insecure gRPC services must be hosted on a HTTP/2-only port. For more information, see ASP.NET Core protocol negotiation.
而jsontranscoding 项目中,appsettings里面的配置是 Http1AndHttp2。文章来源:https://www.toymoban.com/news/detail-434580.html
{
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1AndHttp2"
}
}
}
因此,要同时用就得监听2个http端口,一个http1给web api,一个http2 给gRPC,不知道appsettings.json里面如何写,我是代码实现的:文章来源地址https://www.toymoban.com/news/detail-434580.html
webBuilder.UseStartup<Startup>();
webBuilder.UseKestrel(opts =>
{
opts.ListenAnyIP(5004);
opts.ListenAnyIP(5104, opts => opts.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2);
});
到了这里,关于.net7 通过 JsonTranscoding 实现 gRPC 与 Web API 一鱼两吃的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!