作用
gRPC-gateway是protoc编译器的一个插件,需要提供传统HTTP/JSON
API来满足向后兼容或不支持gRPC的客户端时,gRPC-gateway
可以通过protobuf文件自动生成符合REFTful API的反向代理服务器
安装
1 2 3 4 5 6 7 8 9
| 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()
mux := runtime.NewServeMux() 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) } }
|