作用
gRPC-gateway是protoc编译器的一个插件,需要提供传统HTTP/JSON API来满足向后兼容或不支持gRPC的客户端时,gRPC-gateway 可以通过protobuf文件自动生成符合REFTful API的反向代理服务器
安装
1
2
3
4
5
6
7
8
9
# 安装grpc-gateway插件
go install \
github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway \
github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 \
google.golang.org/protobuf/cmd/protoc-gen-go \
google.golang.org/grpc/cmd/protoc-gen-go-grpc
# 添加依赖
go get github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway用法
buf mod init:生成buf.yaml文件buf lint:检测protobuf格式
生成gRPC服务
写好protobuf文件后,创建一个buf.gen.yaml文件,按如下模板:
1
2
3
4
5
6
7
8
9
10
version: v2
plugins:
- local: protoc-gen-go
out: gen/go
opt:
- paths=source_relative
- local: protoc-gen-go-grpc
out: gen/go
opt:
- paths=source_relative其中out是生成文件的地址,按需修改
执行buf generate就可以生成文件了
生成反向代理
buf.gen.yaml模板如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
version: v2
plugins:
- local: protoc-gen-go
out: gen/go
opt:
- paths=source_relative
- local: protoc-gen-go-grpc
out: gen/go
opt:
- paths=source_relative
- local: protoc-gen-grpc-gateway
out: gen/go
opt:
- paths=source_relative
- generate_unbound_methods=true若需要修改URL,则需要引入google.api.http,protobuf文件添加import "google/api/annotations.proto"
定义service如下:
1
2
3
4
5
6
7
8
service YourService {
rpc Echo(StringMessage) returns (StringMessage) {
option (google.api.http) = {
post: "/v1/example/echo"
body: "*"
};
}
}buf.yaml文件下也需要加入对应的依赖:
1
2
3
4
version: v2
name: buf.build/yourorg/myprotos
deps:
- buf.build/googleapis/googleapis添加依赖后运行buf dep update
编写entrypoint
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package main
import (
"context"
"flag"
"net/http"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/grpclog"
gw "github.com/yourorg/yourrepo/proto/gen/go/your/service/v1/your_service" // 你的网关代码包
)
var (
grpcServerEndpoint = flag.String("grpc-server-endpoint", "localhost:9090", "gRPC server endpoint")
)
func run() error {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
// 创建HTTP mux,用来注册路由
mux := runtime.NewServeMux()
// 设置连接gRPC的选项
opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
// 注册所有需要转发的服务处理函数
err := gw.RegisterYourServiceHandlerFromEndpoint(ctx, mux, *grpcServerEndpoint, opts)
if err != nil {
return err
}
// 启动服务并监听代理
return http.ListenAndServe(":8081", mux)
}
func main() {
flag.Parse()
if err := run(); err != nil {
grpclog.Fatal(err)
}
}