gRPC+gRPC Gateway+swagger小记
前言
本文记录了grpc-gateway的简单使用。
定义proto
先来看看最常规的
syntax = "proto3";
package protos;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
然后加入gateway等相关的内容
syntax = "proto3";
package protos;
// 1 导入 gateway 相关的proto 以及 swagger 相关的 proto
import "google/api/annotations.proto";
import "protoc-gen-swagger/options/annotations.proto";
// 2 定义 swagger 相关的内容
option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = {
info: {
title: "grpc gateway sample";
version: "1.0";
license: {
name: "MIT";
};
};
schemes: HTTP;
};
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {
// 3 标识接口路由
option (google.api.http) = {
post: "/hello_world"
body: "*"
};
}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
从proto生成文件
执行下面的三个命令。
protoc -I . --go_out=plugins=grpc:. hello.proto
protoc -I . --grpc-gateway_out=logtostderr=true:. hello.proto
protoc -I . --swagger_out=logtostderr=true:. hello.proto

实现service和启动service
实现
package services
import (
"context"
pb "grpc-sample/protos"
"log"
)
type server struct{}
func NewServer() *server {
return &server{}
}
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
log.Println("request: ", in.Name)
return &pb.HelloReply{Message: "hello, " + in.Name}, nil
}
启动
package main
import (
"google.golang.org/grpc"
pb "grpc-sample/protos"
"grpc-sample/services"
"log"
"net"
)
const (
PORT = ":9192"
)
func main() {
lis, err := net.Listen("tcp", PORT)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterGreeterServer(s, services.NewServer())
log.Println("rpc services started, listen on localhost:9192")
s.Serve(lis)
}
整合 swagger
先下载swagger ui的静态文件。

把这些文件打包成go文件。
go-bindata --nocompress -pkg swagger -o gateway/swagger/datafile.go third_party/swagger-ui/...

9M。。。
写 gateway
package main
import (
"github.com/elazarl/go-bindata-assetfs"
"log"
"net/http"
"path"
"strings"
"github.com/golang/glog"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"golang.org/x/net/context"
"google.golang.org/grpc"
swagger "grpc-sample/gateway/swagger"
gw "grpc-sample/protos"
)
func run() error {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
gwmux, err := newGateway(ctx)
if err != nil {
panic(err)
}
mux := http.NewServeMux()
mux.Handle("/", gwmux)
mux.HandleFunc("/swagger/", serveSwaggerFile)
serveSwaggerUI(mux)
log.Println("grpc-gateway listen on localhost:8080")
return http.ListenAndServe(":8080", mux)
}
func newGateway(ctx context.Context) (http.Handler, error) {
opts := []grpc.DialOption{grpc.WithInsecure()}
gwmux := runtime.NewServeMux()
if err := gw.RegisterGreeterHandlerFromEndpoint(ctx, gwmux, ":9192", opts); err != nil {
return nil, err
}
return gwmux, nil
}
func serveSwaggerFile(w http.ResponseWriter, r *http.Request) {
if !strings.HasSuffix(r.URL.Path, "swagger.json") {
log.Printf("Not Found: %s", r.URL.Path)
http.NotFound(w, r)
return
}
p := strings.TrimPrefix(r.URL.Path, "/swagger/")
p = path.Join("../protos", p)
log.Printf("Serving swagger-file: %s", p)
http.ServeFile(w, r, p)
}
func serveSwaggerUI(mux *http.ServeMux) {
fileServer := http.FileServer(&assetfs.AssetFS{
Asset: swagger.Asset,
AssetDir: swagger.AssetDir,
Prefix: "third_party/swagger-ui",
})
prefix := "/swagger-ui/"
mux.Handle(prefix, http.StripPrefix(prefix, fileServer))
}
func main() {
defer glog.Flush()
if err := run(); err != nil {
glog.Fatal(err)
}
}
结果如下:

总结
通过grpc-gateway的方式来访问grpc服务,还是挺方便的,不过性能会有所折损。
参考
https://segmentfault.com/a/1190000013513469
gRPC+gRPC Gateway+swagger小记的更多相关文章
- AWS API Gateway Swagger定义
导出Swagger接口定义文件 在AWS API Gateway界面上,可以导出swagger接口定义文件. 而后利用Node js swagger-ui 依赖,生成swagger接口地址 Cloud ...
- LNMP : 502 Bad Gateway 解决小记,真正的原因
站点搬迁到新的server.原先一直都是LAMP.如今改为LNMP. 将重写文件 htaccess改成 nginx的 conf.放到了站点.可仅仅能打开首页,其它重写页面一打开都是不停的载入. 载入等 ...
- gRPC helloworld service, RESTful JSON API gateway and swagger UI
概述 本篇博文完整讲述了如果通过 protocol buffers 定义并启动一个 gRPC 服务,然后在 gRPC 服务上提供一个 RESTful JSON API 的反向代理 gateway,最后 ...
- protobuffer、gRPC、restful gRPC的相互转化
转自:https://studygolang.com/articles/12510 文档 grpc中文文档 grpc-gateway,restful和grpc转换库 protobuf 官网 proto ...
- gRPC错误码 http状态码 provide your APIs in both gRPC and RESTful style at the same time
How gRPC error codes map to HTTP status codes in the response https://github.com/grpc-ecosystem/grpc ...
- 如何在 Knative 中部署 WebSocket 和 gRPC 服务?
作者 | 冬岛 阿里云容器平台工程师 导读:虽然说 Knative 默认就支持 WebSocket 和 gRPC,但在使用中会发现,有时想要把自己的 WebSocket 或 gRPC 部署到 Kna ...
- gRPC应用C++
1. gRPC简述 RPC,远程方法调用,就是像调用本地方法一样调用远程方法. gRPC是Google实现的一种RPC框架,基于HTTP/2标准设计,带来诸如双向流.流控.头部压缩.单 TCP 连接 ...
- 使用nestjs集成grpc具体操作
两个程序中, 提供grpc服务的称为服务端, 调用grpc服务的为客户端, 以下是grpc服务端和客户端的代码编写 1. 创建两个nestjs项目demo1(端口: 3000)和demo2(端 ...
- gRPC学习之一:在CentOS7部署和设置GO
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
随机推荐
- 【使用篇二】Quartz自动化配置集成(17)
出处:https://www.jianshu.com/p/49133c107143 定时任务在企业项目比较常用到,几乎所有的项目都会牵扯该功能模块,定时任务一般会处理指定时间点执行某一些业务逻辑.间隔 ...
- 剑指Offer-38.平衡二叉树(C++/Java)
题目: 输入一棵二叉树,判断该二叉树是否是平衡二叉树. 分析: 可以从根节点开始遍历每一个节点,求得节点左右子树的最大高度,判断是不是平衡二叉树.这样做的问题在于会重复遍历节点,造成不必要的浪费. 所 ...
- BZOJ2301/LG2522 「HAOI2011」Problem B 莫比乌斯反演 数论分块
问题描述 BZOJ2301 LG2522 积性函数 若函数 \(f(x)\) 满足对于任意两个最大公约数为 \(1\) 的数 \(m,n\) ,有 \(f(mn)=f(m) \times f(n)\) ...
- 日记o3o
12.17 段考超级烂,连sts都没考过,但是今晚来机房,nj发邮件的时候也给我发了,看来是可以继续学竞赛啦,很快心,也挺不开心的,毕竟以后想要跟上文化课就要很努力了,有能力但是得去花时间啊,寒假又要 ...
- [C++]Game模板-正面视角
前言 本来是想打一个小游戏的-- 可是打到一半思路断了-- 只打出了模板--先把模板拿出来放着 Code //head #include <iostream> #include <c ...
- 工作笔记 之 Linux服务搭建
No.1 linux环境下安装nginx步骤 Nginx (engine x) 是一款轻量级的Web 服务器.反向代理服务器.电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行. ...
- 一起学Android之音频视频
概述 Android多媒体框架支持各种常见的媒体类型,可以很容易地将音频.视频和图像集成到App中.通过MediaPlayer Api,可以从应用程序资源(RAW).文件系统或网络上数据流资源来播放音 ...
- go-爬图片
go语言爬取图片 注:动态加载出来的爬取不到,或怕取出来图片出错,代码中的网页是可以正常爬取的 package main import ( "fmt" "io" ...
- nmap的简单使用
主机探测 1.扫描单个主机 nmap 192.168.1.2 2.扫描整个子网 nmap 192.168.1.1/24 3.扫描多个目标 nmap 192.168.1.1 192.168.1.1.5 ...
- Nginx之HTTPS
Nginx之HTTPS 1. HTTPS安全证书基本概述 为什么需要使用HTTPS,因为HTTP不安全,当我们使用http网站时,会遭到劫持和篡改,如果采用https协议,那么数据在传输过程中是加密的 ...