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

.NET7 gRPC JSON转码+OpenAPI的更多相关文章

  1. 关于.Net 7.0 RC gRPC JSON 转码为 Swagger/OpenAPI文档的注意事项

    大家好,我是失业在家,正在找工作的博主Jerry,找工作之余,看到.Net 7.0 RC2发布了,就想测试下.Net 7.0 RC2 gRPC JSON 转码为 Swagger/OpenAPI文档的特 ...

  2. 修改json源码支持datetime序列化

    修改json源码支持datetime序列化 import json import datetime now = datetime.datetime.today() json.dumps(now) 抛出 ...

  3. Newtonsoft.Json源码中的C#预处理指令

    cs文件中包含以指令: #if !(NET35 || NET20 || PORTABLE40) 记事本打开[Newtonsoft.Json.Net20.csproj]可看到以下代码: <Defi ...

  4. Newtonsoft.Json源码的solution打开之后,无法加载project

    无法加载项目 https://github.com/JamesNK/Newtonsoft.Json C:\repository\GitHub\Other\Newtonsoft.Json\Src\New ...

  5. Dapr实现.Net Grpc服务之间的发布和订阅,并采用WebApi类似的事件订阅方式

    大家好,我是失业在家,正在找工作的博主Jerry,找工作之余,总结和整理以前的项目经验,动手写了个洋葱架构(整洁架构)示例解决方案 OnionArch.其目的是为了更好的实现基于DDD(领域驱动分析) ...

  6. 【译】.NET 7 预览版 1 中的 ASP.NET Core 更新

    原文 | Daniel Roth 翻译 | 郑子铭 .NET 7 预览版 1 现已推出!这是 .NET 下一个主要版本的第一个预览版,其中将包括使用 ASP.NET Core 进行 Web 开发的下一 ...

  7. 我又造了个轮子:GrpcGateway

    我个人对GRPC是比较感兴趣的,最近在玩通过前端调用GRPC.通过前端调用GRPC业界有两种方式:GRPC Web和GRPC JSON转码. GRPC Web 通过JS或者Blazor WASM调用G ...

  8. .NET Conf 2022 &ndash; 11 月 8 日至 10 日

    .NET Conf 2022 下周就正式开启了,时间是美国时间的 11月8日至10日..NET Conf 2022是一个免费的,为期三天的, 虚拟开发人员活动提供多种实时会话,其中包括来自社区和 .N ...

  9. gRPC源码分析2-Server的建立

    gRPC中,Server.Client共享的Class不是很多,所以我们可以单独的分别讲解Server和Client的源码. 通过第一篇,我们知道对于gRPC来说,建立Server是非常简单的,还记得 ...

随机推荐

  1. 【Java】学习路径57-TCP协议客户端与服务器端的关闭

    在TCP协议中,如果发送端(客户端)关闭了,那么接收端(服务器端)端就会收到这个消息. 那么接收端(服务器端)怎么知道的呢? 我们进行实验: 首先在发送端中编写一段程序,当用户输入"end& ...

  2. python数据精度问题

    一.python运算时精度问题: 1.运行时精度问题在Python中(其他语言中也存在这个问题,这是计算机采用二进制导致的),有时候由于二进制和十进制之间对应问题会导致数值的精度问题,比如无法用有限个 ...

  3. KingbaseES 与 Oracle 用户口令管理与资源管理

    一.概述 KingbaseES可以对用户口令与用户占用资源进行必要的管理.其管理方式,在这里与Oracle数据库进行参考比较. KingbaseES 使用扩展插件建立的系统参数,这组参数可以对数据库资 ...

  4. KingbaseES sys_prewarm 扩展

    Oracle 在查询数据 可以通过cache hint 所访问的数据cache 到数据库buffer,对于KingbaseES,如何将数据加载到cache 了?sys_prewarm 扩展插件可以实现 ...

  5. CDH6.2.0 搭建大数据集群

    1. 资料准备 现在官网https://www.cloudera.com 需要注册账号,未来可能会收费等问题,十分麻烦,这里有一份我自己百度云的备份 链接: https://pan.baidu.com ...

  6. 干货分享!JAVA诊断工具Arthas在Rainbond上实践~

    别再担心线上 Java 业务出问题怎么办了,Arthas 帮助你解决以下常见问题: 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception? 我改的代码为什么没有执行到?难道是我没 ...

  7. 对比es6class类和构造函数

    构造函数 在原来class 类这个语法糖没有出来之前 我们一般会把方法挂在prototype 上 为了防止过多的开辟内存 1 // 构造函数------------------------------ ...

  8. 配置联想IMM使用AD账户登录

    IMM是联想(IBM)服务器的管理卡Integrated Management Module的缩写,现在是第二个版本.通过它可以远程管理服务器,就像你在服务器面前操作一样.可以修改BIOS设置,可以重 ...

  9. Elasticsearch API响应的一些常用选项

    我们可以点击Elasticsearch API以获取所需的响应,但是如果要修改API响应,以便我们更改显示格式或过滤掉某些字段,然后我们可以将这些选项与查询一起应用. 有一些常见的选项可以适用于API ...

  10. Docker Compose配置文件详解(V3)

    Docker Compose配置文件是Docker Compose的核心,用于定义服务.网络和数据卷.格式为YAML,默认路径为./docker-compose.yml,可以使用.yml或.yaml扩 ...