grpc-gateway:讓你同時擁有 grpc 和 http 接口,一鍵生成 swagger 文檔

編寫 proto 文件

syntax = "proto3";

package pet.service.v1;
option go_package = ".;petpb";

import "google/protobuf/empty.proto";
import "google/api/annotations.proto";
import "google/protobuf/timestamp.proto";

service PetService {
  rpc ListPet (google.protobuf.Empty) returns (PetList) {
    option (google.api.http) = {
      get: "/v1/pets"
    };
  }

  rpc GetPet (Id) returns (Pet) {
    option (google.api.http) = {
      get: "/v1/pets/{id}"
    };
  }

  rpc CreatePet (Pet) returns (Pet) {
    option (google.api.http) = {
      post: "/v1/pets"
    };
  }

  rpc UpdatePet (Pet) returns (Pet) {
    option (google.api.http) = {
      put: "/v1/pets/{id}"
    };
  }

  rpc DeletePet (Id) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/pets/{id}"
    };
  }
}

message Id {
  string id = 1;
}

message PetList {
  repeated Pet items = 1;
}

message Pet {
  string id = 1;
  google.protobuf.Timestamp createdAt = 2;
  google.protobuf.Timestamp updatedAt = 3;
  string name = 4;
  string type = 5;
  string  sex = 6;
  uint32 age = 7;
  bool owned = 8;
}

先決條件:html

# MacOS
brew install protobuf
  • grpc-gateway protoc 插件已安裝
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

生成樁代碼及 swagger 文檔:nginx

protoc -I/usr/local/include -I. \
        -I${GOPATH}/protobuf \
        --go_out . --go_opt paths=source_relative \
        --go-grpc_out . --go-grpc_opt paths=source_relative \
        --grpc-gateway_out . --grpc-gateway_opt paths=source_relative \
        --grpc-gateway_opt logtostderr=true \
        --grpc-gateway_opt generate_unbound_methods=true \
        --grpc-gateway_opt register_func_suffix=GW \
        --grpc-gateway_opt allow_delete_body=true \
        --openapiv2_out . --openapiv2_opt logtostderr=true \
        pet.proto

生成文檔

先決條件:git

  • docker 已安裝並運行

有了 swagger.json 藉助 swagger 相關的工具咱們就能夠生成文檔了。這裏咱們使用 redoc,經過容器啓動一個 server 渲染文檔:github

docker run -it --rm -p 80:80 \
      -v $$(pwd)/pet.swagger.json:/usr/share/nginx/html/swagger.yaml \
      -e SPEC_URL=swagger.yaml redocly/redoc

瀏覽器訪問 localhost,就能打開漂亮的文檔頁面了:
imagegolang

實現接口,啓動服務

先啓動 grpc server,這裏同時經過 grpc-middleware 注入了一些經常使用中間件:docker

s := grpc.NewServer(
    grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
        grpc_opentracing.UnaryServerInterceptor(),
        grpc_prometheus.UnaryServerInterceptor,
        grpc_logrus.UnaryServerInterceptor(logrusEntry),
        grpc_recovery.UnaryServerInterceptor(),
    )),
)
petpb.RegisterPetServiceServer(s, petsvc.NewPetService())

log.Infof("grpc server start: %s", addr)
if err := s.Serve(lis); err != nil {
    log.Fatalf("failed to serve: %v", err)
}

再啓動 grpc-gateway,這裏依賴 grpc server 的地址:shell

err := gw.RegisterPetServiceGWFromEndpoint(ctx, mux, grpcAddr, opts)
if err != nil {
    return err
}

log.Infof("gateway server start: %s", gatewayAddr)
http.ListenAndServe(gatewayAddr, mux)

原理是在 grpc server 以前作了一層 http 反向代理,將 http 請求轉爲 protobuf 送給後端的 grpc server,對返回值再作一次轉換。官方架構圖 畫的比較清楚了。json

完整代碼

先決條件:segmentfault

  • make 命令已安裝

proto 及 swagger:https://github.com/win5do/go-...後端

執行 make gen 生成 grpc 樁代碼及 swagger.json 文檔。

執行 make serve-docs 啓動容器渲染文檔。

grpc 及 gateway:https://github.com/win5do/go-...

Reference

https://github.com/grpc-ecosy...

相關文章
相關標籤/搜索