让 gRPC 提供 REST 服务

Intro

gRPC 是一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。

gRPC 基于 HTTP/2 标准设计,带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用请求等特。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。

gRPC 是一个很流行的现代化 RPC 框架,它以 HTTP/2 为通信协议基础,gRPC 默认使用 protocol buffers 作为接口定义语言,来描述服务接口和有效载荷消息结构。

尽管 gRPC 有很多应用,但是更为常用的还是基于 HTTP/1.1 的 REST 服务,应用更广,那么能否让 gRPC 同时提供 REST 服务呢?答案是肯定的,现在有一个实验性的项目(gRPC HTTP API )正在进行,如果觉得这个项目不错,欢迎在 Github 上进行反馈,将你的意见反馈给 gRPC 团队或者去点个赞以提升项目的优先级 https://github.com/grpc/grpc-dotnet/issues/167

Sample

Proto

首先我们来看一下 proto file:

syntax = "proto3";
//
import "google/api/annotations.proto"; package greet.v1; service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {
option (google.api.http) = {
get: "/v1/greeter/{name}"
};
}
rpc SayHelloFrom (HelloRequestFrom) returns (HelloReply) {
option (google.api.http) = {
post: "/v1/greeter"
body: "*"
};
}
} message HelloRequest {
string name = 1;
} message HelloRequestFrom {
string name = 1;
string from = 2;
} message HelloReply {
string message = 1;
}

和之前相比的变化就是引入了 google/api/annotations.proto,然后在声明方法的地方声明了 http 请求的方式和路由

Project update

除了 proto file 变化之外,我们还需要引用 Microsoft.AspNetCore.Grpc.HttpApi 这个包,为了更好的和 swagger 整合,也可以引用 Microsoft.AspNetCore.Grpc.Swagger 这是一个 swagger 的扩展

在 Startup 中注册服务:

services.AddGrpcHttpApi();

如果引用了 swagger,也要注册相应的服务:

services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
})
.AddGrpcSwagger();

这样就可以了

Client Sample

客户端调用示例如下:

using var client = new HttpClient()
{
DefaultRequestVersion = HttpVersion.Version20,
DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher,
};
await InvokeHelper.TryInvokeAsync(async () =>
{
var responseText = await client.GetStringAsync("https://localhost:5001/v1/greeter/test");
Console.WriteLine($"Response from https endpoint: {responseText}");
});
await InvokeHelper.TryInvokeAsync(async () =>
{
var responseText = await client.GetStringAsync("http://localhost:5000/v1/greeter/test");
Console.WriteLine($"Response from http endpoint: {responseText}");
}); //
await InvokeHelper.TryInvokeAsync(async () =>
{
var responseText = await client.GetStringAsync("http://localhost:5000/v1/todo");
Console.WriteLine($"Response from todo endpoint: {responseText}");
});

客户端输出示例:

服务器端输出示例:

完整的测试代码可以在 Github 获取 https://github.com/WeihanLi/SamplesInPractice/tree/master/GrpcSample

Known Issues

JSON Serialization

现在的 JSON 序列化是基于Google.Protobuf,这个实现有两个问题:

  • 它是线程阻塞的(非 async)
  • 没有做过性能优化

Http proto file

需要在最终用户的源代码中添加 google / api / annotations.proto和 google / api / http.proto,以便Protobuf编译器可以将它们与用户的proto文件一起加载。 如果以某种方式用户不必关心这些文件,那将是更好的开发人员体验。

More

这个项目使用下来感觉还是挺方便的,相当于在 proto 文件中加了 http 请求相关的注解,就可以自动提供 REST 服务,这样对于 gRPC 和 REST 服务的整合就很方便了

唯一让我觉得有一些美中不足的地方就是 http 只支持 Http2,如果 http 协议要支持 http1.1 的话,http请求 必须要 https,如果是 http2 就可以比较好的支持 http,但是大部分的客户端都是 httpClient 都是直接请求的,大多没有设置过 Http Version,要手动设置 http2 才可以

如果觉得还不错,记得去 GitHub 上反馈哈 https://github.com/grpc/grpc-dotnet/issues/167

References

让 gRPC 提供 REST 服务的更多相关文章

  1. grpc提供http服务

    package main import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials&qu ...

  2. .net core grpc consul 实现服务注册 服务发现 负载均衡(二)

    在上一篇 .net core grpc 实现通信(一) 中,我们实现的grpc通信在.net core中的可行性,但要在微服务中真正使用,还缺少 服务注册,服务发现及负载均衡等,本篇我们将在 .net ...

  3. ASP.NET Core gRPC 使用 Consul 服务注册发现

    一. 前言 gRPC 在当前最常见的应用就是在微服务场景中,所以不可避免的会有服务注册与发现问题,我们使用gRPC实现的服务可以使用 Consul 或者 etcd 作为服务注册与发现中心,本文主要介绍 ...

  4. .Net Core Grpc Consul 实现服务注册 服务发现 负载均衡

    本文是基于..net core grpc consul 实现服务注册 服务发现 负载均衡(二)的,很多内容是直接复制过来的,..net core grpc consul 实现服务注册 服务发现 负载均 ...

  5. 微服务架构攀登之路(四)之使用gRPC构建微服务

    做一个处理用户信息的微服务 客户端通过用户名,可以从服务端查询用户的基本信息 gRPC proto user.proto 定义客户端请求.服务端响应的数据格式 user.pb.go 自动生成的,为数据 ...

  6. 如何基于gRPC沟通微服务框架

    本文我们来讲解一下如何使用 gRPC构建微服务,gRPC是一个开源框架,可用于构建可扩展且高性能的微服务并创建服务之间的通信. 背景 随着企业越来越多地转向微服务,对构建这些微服务的低延迟和可扩展框架 ...

  7. Windows Azure HandBook (2) Azure China提供的服务

    <Windows Azure Platform 系列文章目录> 对于传统的自建数据中心,从底层的Network,Storage,Servers,Virtualization,中间层的OS, ...

  8. 提供RESTful服务

    RESTful广泛运用于互联网服务,而在企业应用中,大部分场景仍然是RPC服务,这是由于企业应用的业务复杂性造成的.但是基于SOAP的RPC服务也存在很多的弊端,比如服务异步处理比较麻烦,大部分RPC ...

  9. 第13章 使用Bind提供域名解析服务

    章节简述: 本章节将让您理解DNS服务程序的原理,学习正向解析与反向解析实验,掌握DNS主服务器.从服务器.缓存服务器的部署方法. 够熟练配置区域信息文件与区域数据文件,以及通过使用分离解析技术让不同 ...

随机推荐

  1. 最简单直接地理解Java软件设计原则之依赖倒置原则

    理论性知识 定义 依赖倒置原则,Dependence Inversion Principle (DIP) 高层模块不应该依赖低层模块.二者都应该依赖其抽象. 抽象不应该依赖细节,细节应该依赖抽象. 针 ...

  2. Language Guide (proto3) | proto3 语言指南(二)标量值类型

    标量值类型 标量消息字段可以具有以下类型之一 -- 下表显示了.proto文件中指定的类型,以及自动生成的类中相应的类型: .proto Type 说明 C++ Type Java Type Pyth ...

  3. 后台获取日期值,前台Js对日期进行操作

    需求描述: 方法一: 方法二: 一些标签常用隐藏方法: 需求描述: 在初始化页面的时候,需要根据系统当前的时间对前台JSP页面的某项进行值的初始化,若前台JSP标签没有相关可以初始化的属性,那么可以从 ...

  4. K8s (常用命令)

    查看集群信息: [root@kubernetes-master pods]# kubectl cluster-infoKubernetes master is running at http://lo ...

  5. mysql 用户 登陆 权限相关

    1. CREATE USER 'dog2'@'localhost' IDENTIFIED BY ''; 将"localhost"改为"%",表示在任何一台电脑上 ...

  6. 31.FTP简介

    1.FTP 是一种在互联网中进行文件传输的协议,基于客户端/服务器模式,默认使用20.21号端口,其中端口20(数据端口)用于进行数据传输,端口21(命令端口)用于接受客户端发出的相关FTP 命令与参 ...

  7. python通过注册表准确获得Windows桌面路径(为了一定的通用性)

    参考文章:https://blog.csdn.net/u013948858/article/details/75072873 使用python内置的winreg模块,非常方便: import winr ...

  8. (史上最全)SNP位点与转录因子结合特异性数据库:GVATdb

    众所周知,全基因组关联分析(GWAS)发现的很多变异位点基本为非编码,这些变异位点1)要么调控基因表达(eQTL); 2)要么影响增强子活性; 3)要么影响转录因子(TF)结合特异性; 4)要么啥也不 ...

  9. Educational Codeforces Round 90 (Rated for Div. 2) A. Donut Shops(数学)

    题目链接:https://codeforces.com/contest/1373/problem/A 题意 有两种包装的甜甜圈,第一种 $1$ 个 $a$ 元,第二种 $b$ 个 $c$ 元,问买多少 ...

  10. Codeforces Round #628 (Div. 2) A. EhAb AnD gCd(LCM & GCD)

    题意: GCD(a,b) + LCM(a,b) = n,已知 n ,求 a,b. 思路: 设 gcd(a, b) = k, a = xk, b = yk , k + ab / k = n xy = n ...