.net7 通过 JsonTranscoding 实现 gRPC 与 Web API 一鱼两吃

目标

    在一个网站内,用一套proto即提供gPRC 调用,又提供 Web API 调用。

实现方法

    根据微软官方James Newton King(Newtonsoft.json 作者)的文章,.net7 里面提供了 JsonTranscoding 特性,只需要三步(翻译自链接中的文档):

  1. 第一步用vs2022创建一个 .net7的 gRPC service Create a gRPC client and service
  2. 第二步,添加nuget包 Microsoft.AspNetCore.Grpc.JsonTranscoding。在服务的 startup.cs 文件里添加一句 services.AddGrpc().AddJsonTranscoding();
  3. 最后在 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。

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

    因此,要同时用就得监听2个http端口,一个http1给web api,一个http2 给gRPC,不知道appsettings.json里面如何写,我是代码实现的:

webBuilder.UseStartup<Startup>();
webBuilder.UseKestrel(opts =>
{                        
	opts.ListenAnyIP(5004);
	opts.ListenAnyIP(5104, opts => opts.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2);
});

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值