使用 JSON 协议的 gRPC
JSON payload 实现简易的请求和响应的内省。
介绍
大家经常说 gRPC 是基于 Google Protocol Buffers payload 格式的,然而这不完全正确。gRPC payload 的默认格式是 Protobuf,但是 gRPC-Go 的实现中也对外暴露了 Codec interface ,它支持任意的 payload 编码。我们可以使用任何一种格式,包括你自己定义的二进制格式、flatbuffers、或者使用我们今天要讨论的 JSON ,作为请求和响应。
服务端准备
我已经基于 JSON payload 实现 了 grpc/encoding.Codec,创建了一个示例库。服务端的准备工作仅仅像引入一个包那样简单;
import _ "github.com/johanbrandhorst/grpc-json-example/codec"
这行代码注册了一个基于 json 内容的子类型 JSON Codec,我们在后面会看到这对于方便记忆很重要。
Request 示例
gRPC 客户端
使用 gRPC 客户端,你只需要使用合适的内容子类型作为 grpc.DialOption 来初始化:
import "github.com/johanbrandhorst/grpc-json-example/codec"
func main() {
conn := grpc.Dial("localhost:1000",
grpc.WithDefaultCallOptions(grpc.CallContentSubtype(codec.JSON{}.Name())),
)
}
示例库代码包含有完整示例的客户端。
cURL
更有趣的是,现在我们可以用 cURL 写出请求(和读取响应)!请求示例:
$ Echo -en '\x00\x00\x00\x00\x17{"id":1,"role":"ADMIN"}' | curl -ss -k --http2 \
-H "Content-Type: application/grpc+json" \
-H "TE:trailers" \
--data-binary @- \
https://localhost:10000/example.UserService/AddUser | od -bc
0000000 000 000 000 000 002 173 175
\0 \0 \0 \0 002 { }
0000007
$ Echo -en '\x00\x00\x00\x00\x17{"id":2,"role":"GUEST"}' | curl -ss -k --http2 \
-H "Content-Type: application/grpc+json" \
-H "TE:trailers" \
--data-binary @- \
https://localhost:10000/example.UserService/AddUser | od -bc
0000000 000 000 000 000 002 173 175
\0 \0 \0 \0 002 { }
0000007
$ Echo -en '\x00\x00\x00\x00\x02{}' | curl -k --http2 \
-H "Content-Type: application/grpc+json" \
-H "TE:trailers" \
--data-binary @- \
--output - \
https://localhost:10000/example.UserService/ListUsers
F{"id":1,"role":"ADMIN","create_date":"2018-07-21T20:18:21.961080119Z"}F{"id":2,"role":"GUEST","create_date":"2018-07-21T20:18:29.225624852Z"}
解释
使用 cURL 发送请求需要手动把 gRPC HTTP2 message payload header 加到 payload:
'\x00\x00\x00\x00\x17{"id":1,"role":"ADMIN"}'
#<-->----------------------------------------- Compression boolean (1 byte)
# <-------------->------------------------- Payload size (4 bytes)
# <--------------------->-- JSON payload
请求头必须包含 TE 和正确的 Content-Type:
-H "Content-Type: application/grpc+json" -H "TE:trailers"
在 Content-Type 头中 application/grpc+ 后的字符串需要与服务端注册的 codec 的 Name() 相吻合。这就是内容子类.
endpoint 需要与 proto 包的名字、服务和方法三者的名字都匹配:
https://localhost:10000/example.UserService/AddUser
响应头与请求头一致:
'\0 \0 \0 \0 002 { }'
#<-->------------------------ Compression boolean (1 byte)
# <------------>---------- Payload size (4 bytes)
# <--->-- JSON payload
总结
我们已经展示了我们可以轻易地在 gRPC 中使用 JSON payload,甚至可以用 JSON payload 直接发送 cURL 请求到我们的 gRPC 服务,没有代理,没有 grpc 网关,除了引入一个必要的包也没有其他的准备工作。
如果你对本文感兴趣,或者有任何问题和想法,请在 @johanbrandhorst 上或 在 Gophers Slack jbrandhorst 下联系我。很高兴听到你的想法。
via: https://jbrandhorst.com/post/grpc-json/
作者:Johan Brandhorst 译者:lxbwolf 校对:polaris1119
使用 JSON 协议的 gRPC的更多相关文章
- ETCD:HTTP JSON API通过gRPC网关
原文地址:HTTP JSON API through the gRPC gateway etcd v3 使用 gRPC 作为消息协议.etcd项目包括一个基于gRPC的Go客户端和一个命令行工具,et ...
- 接口自动化 基于python实现的http+json协议接口自动化测试框架源码(实用改进版)
基于python实现的http+json协议接口自动化测试框架(实用改进版) by:授客 QQ:1033553122 欢迎加入软件性能测试交流QQ群:7156436 目录 1. ...
- soapUI 使用soapUI测试http+json协议接口简介
使用soapUI测试http+json协议接口简介 by:授客 QQ:1033553122 SoapUI-Pro-x64-5.1.2_576025(含破解文件),软件下载地址: http://pan. ...
- 命令行参数 && json 协议 && 自定义 error 类型
命令行参数 在写代码的时候,在运行程序做一些初始化操作的时候,往往会通过命令行传参数到程序中,那么就会用到命令行参数 例如,指定程序运行的模式和级别: go run HTTPServer.go --m ...
- 八、golang文本操作、json协议
一.终端读写 操作终端相关文件语句常量,go所有的都是接口 os.Stdin:标准输入 os.Stdout:标准输入,只要实现输出这个接口,打印到终端, os.Stderr:标准错误输出 os.Ope ...
- Python 基于python实现的http+json协议接口自动化测试框架源码(实用改进版)
目录 1. 写在前面 2. 开发环境 3. 大致流程 4. 框架简介 5. 运行结果展示 6. 文件与配置 7. 测试接口实例 n ...
- 前后端分离项目,标准json协议格式参考
正常返回 { "code": 0, "data": [{ "cTime": "2018-11-19 14:46:16" ...
- grpc-gateway:grpc转换为http协议对外提供服务
我所在公司的项目是采用基于Restful的微服务架构,随着微服务之间的沟通越来越频繁,就希望可以做成用rpc来做内部的通讯,对外依然用Restful.于是就想到了google的grpc. 使用grpc ...
- Dubbo 在跨语言和协议穿透性方向的探索:支持 HTTP/2 gRPC
Dubbo 在跨语言和协议穿透性方向上的探索:支持 HTTP/2 gRPC 和 Protobuf 本文整理自刘军在 Dubbo 成都 meetup 上分享的<Dubbo 在多语言和协议穿透性方向 ...
随机推荐
- 题解 UVA1193 Radar Installation
原题 PDF OJ 思路 分析 因为半径d已经确定,所以对于每个点,我们可以算出它在x 轴上的覆盖位置线段LR,如图. 此问题便转为: 对于 n 个区间,每个区间内至少有1个点,求最少点数. 算法 我 ...
- 仔细想想SpringAOP也不难嘛,面试没有必要慌
文章已托管到GitHub,大家可以去GitHub查看阅读,欢迎老板们前来Star! 搜索关注微信公众号 码出Offer 领取各种学习资料! LOGO SpringAOP 一.什么是AOP AOP(As ...
- java大数据最全课程学习笔记(5)--MapReduce精通(一)
目前CSDN,博客园,简书同步发表中,更多精彩欢迎访问我的gitee pages 目录 MapReduce精通(一) MapReduce入门 MapReduce定义 MapReduce优缺点 优点 缺 ...
- Mnist手写数字识别 Tensorflow
Mnist手写数字识别 Tensorflow 任务目标 了解mnist数据集 搭建和测试模型 编辑环境 操作系统:Win10 python版本:3.6 集成开发环境:pycharm tensorflo ...
- React native项目后期调整UI总结
字体 fontSize: 14, marginLeft: 10, marginTop: 2, fontFamily: 'ABBvoiceCNSG-Regular', 布局 paddingHorizon ...
- SpringSecurity+Oauth2+Jwt实现toekn认证和刷新token
简单描述:最近在处理鉴权这一块的东西,需求就是用户登录需要获取token,然后携带token访问接口,token认证成功接口才能返回正确的数据,如果访问接口时候token过期,就采用刷新token刷新 ...
- 控制语句—for循环、while循环
for循环 基本结构: for(初始条件1:循环条件2:状态改变3){ 循环体4 } 运行流程:1-2-4-3-2-4 while循环 基本结构: var i=0 //初始条件 1 while(i&l ...
- Springboot+Mybatis+Clickhouse+jsp 搭建单体应用项目(一)
一.服务器安装clickhouse服务 参阅 :https://www.cnblogs.com/liuyangfirst/p/13379064.html 二.连接数据库 成功 三.新建库 CREATE ...
- PHP zip_entry_read() 函数
定义和用法 zip_entry_read() 函数从打开的 zip 档案中获取内容.高佣联盟 www.cgewang.com 如果成功,该函数则返回项目的内容.如果失败,则返回 FALSE. 语法 z ...
- CF R 635 div1 C Kaavi and Magic Spell 区间dp
LINK:Kaavi and Magic Spell 一打CF才知道自己原来这么菜 这题完全没想到. 可以发现 如果dp f[i][j]表示前i个字符匹配T的前j个字符的方案数 此时转移变得异常麻烦 ...