-
运行代码
git clone git@github.com:WeCanRun/grpc-example.git make
-
访问
swagger-ui
首页http://localhost:9001/swagger-ui/
-
输入
swagger
文档地址, 点击Explore
http://localhost:9001/swagger/all.swagger.json
- 版本信息
libprotoc 3.21.5 protoc-gen-go v1.28.1 protoc-gen-go-grpc 1.1.0
- 定义
proto
文件proto/*.proto
- 生成
grpc
代码protoc -I . -I ../../googleapis/googleapis --go_out ./ --go_opt paths=source_relative --go-grpc_out=require_unimplemented_servers=false:./ --go-grpc_opt paths=source_relative proto/*.proto
- 创建
grpc
服务器,并注册相关服务cmd/server/server.go
- 修改
proto
文件,加入grpc-gatway
相关配置 - 生成
grpc-gateway
相关代码protoc -I . -I ../../googleapis/googleapis --grpc-gateway_out . --grpc-gateway_opt logtostderr=true --grpc-gateway_opt paths=source_relative --grpc-gateway_opt generate_unbound_methods=true proto/*.proto
- 使用
protoc-gen-openapiv2
生成swagger
文档protoc -I . -I ../../googleapis/googleapis --openapiv2_out ./docs --openapiv2_opt use_go_templates=true --openapiv2_opt logtostderr=true --openapiv2_opt allow_merge=true,merge_file_name=all proto/*.proto
- 增加
swagger
路由mkdir third_patry && cd third_patry && git clone git@github.com:swagger-api/swagger-ui.git mkdir swagger && cp -r swagger-ui/dist/* swagger/ && rm -rf swagger-ui/ go get -u github.com/go-bindata/go-bindata/... go get -u github.com/elazarl/go-bindata-assetfs/... go-bindata --nocompress -pkg swagger -o pkg/swagger/data.go third_party/swagger/...
func serveSwaggerFile() func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { log.Println("start serveSwaggerFile") 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("docs/", 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", }) prefix := "/swagger-ui/" mux.Handle(prefix, http.StripPrefix(prefix, fileServer)) }
- 增加拦截器
func AccessInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { requestLog := "access request log: method: %s, begin_time: %d, request: %v" begin := time.Now().Unix() log.Printf(requestLog, info.FullMethod, begin, req) resp, err := handler(ctx, req) end := time.Now().Unix() respLog := "access response log: method: %s, begin_time: %d, end_time: %d, spend_time: %d, response: %v" log.Printf(respLog, info.FullMethod, begin, end, end - begin, resp) return resp, err }
func NewGrpcServer() *grpc.Server { opts := []grpc.ServerOption{ grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer( middleware.AccessInterceptor, grpc_ctxtags.UnaryServerInterceptor(), grpc_opentracing.UnaryServerInterceptor(), grpc_recovery.UnaryServerInterceptor(), )), } server := grpc.NewServer(opts...) // 注册服务 pb.RegisterSearchServiceServer(server, service.NewSearch()) pb.RegisterPubSubServiceServer(server, service.NewPubSub()) reflection.Register(server) return server }
- 使用
metadata
自定义认证 - 链路追踪
jaeger