gRPC学习之六:gRPC-Gateway集成swagger

  • 还要把swaggerdemo.proto中提到的protoc-gen-swagger/options/annotations.proto文件放在合适的地方,以便使用swaggerdemo.proto的时候能找到此annotations.proto文件,执行以下命令:

cd $GOPATH/src

cp -r ./github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger ./

  • 上述命令中的protoc-gen-swagger文件夹,是在前文的操作中下载好的;

生成gRPC、gRPC-Gateway所需的go源码

  • 生成gRPC、gRPC-Gateway所需的go源码,这样的操作在前面已经做过,这里用swaggerdemo.proto再做一次,先进入目录$GOPATH/src/swaggerdemo

  • 执行以下命令,生成gRPC所需源码:

protoc -I. \

-I$GOPATH/src \

-I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \

–go_out=plugins=grpc:. \

swaggerdemo.proto

  • 执行以下命令,生成gRPC-Gateway所需源码:

protoc -I. \

-I$GOPATH/src \

-I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \

–grpc-gateway_out=logtostderr=true:. \

swaggerdemo.proto

生成swagger所需的json文件

  • 还是在目录$GOPATH/src/swaggerdemo,执行以下命令,生成swagger所需json:

protoc -I. \

-I$GOPATH/src \

-I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \

–swagger_out=logtostderr=true:. \

swaggerdemo.proto

  • 此时的$GOPATH/src/swaggerdemo目录下新增以下三个文件:
  1. swaggerdemo.pb.go:gRPC所需的go文件

  2. swaggerdemo.pb.gw.go:gRPC-Gateway所需的go文件

  3. swaggerdemo.swagger.json:swagger-ui要用的json文件,依据此文件,swagger展现的页面中会有gRPC-Gateway暴露的服务和参数定义,可以在页面上发起请求

生成swagger-ui的go文件

  • 要想在服务中提供swagger的web页面,需要将swagger-ui的源码转为go文件,步骤如下:
  1. 接下来的命令会从Github下载swagger-ui的源码,这个文件本该从swagger官方下载,但是我这里尝试多次后发现,下载得到的zip包很容器出现文件损坏而无法解压缩的情况,于是我将此文件放在了自己的Github上,下面的操作也是从我自己的Github下载的,但实际上此文件和swagger官方的并无区别;

  2. 进入目录$GOPATH/src/swaggerdemo,执行以下命令下载swagger-ui源码,并放入指定位置:

wget https://raw.githubusercontent.com/zq2599/blog_download_files/master/files/swagger-ui.zip -O swagger-ui.zip \

&& unzip swagger-ui.zip \

&& mkdir -p $GOPATH/src/swaggerdemo/third_party/ \

&& mv ./swagger-ui-3.38.0/dist $GOPATH/src/swaggerdemo/third_party/ \

&& mv $GOPATH/src/swaggerdemo/third_party/dist $GOPATH/src/swaggerdemo/third_party/swagger-ui \

&& rm -f ./swagger-ui.zip \

&& rm -rf ./swagger-ui-3.38.0

  1. 执行以下命令新建文件夹,该文件夹用来存放稍后生成的swagger-ui的go源码:

mkdir -p $GOPATH/src/swaggerdemo/pkg/ui/data/swagger

  1. 执行以下命令,将swagger-ui源码转为datafile.go文件:

cd $GOPATH/src/swaggerdemo/

go-bindata --nocompress -pkg swagger -o pkg/ui/data/swagger/datafile.go third_party/swagger-ui/…

  1. 这时候在$GOPATH/src/swaggerdemo/pkg/ui/data/swagger目录下生成了文件datafile.go
  • 所有文件和材料已经准备完成,开始编码;

编写gRPC的服务端代码

  • 按照swaggerdemo.proto的配置新建一个gRPC服务,步骤如下:
  1. 新建文件夹$GOPATH/src/swaggerdemo/server;

  2. 在新建的server文件夹下新增文件server.go,内容如下,只是个普通的gRPC服务而已:

package main

import (

“context”

“log”

“net”

“google.golang.org/grpc”

pb “swaggerdemo”

)

const (

port = “:50051”

)

// 定义结构体,在调用注册api的时候作为入参,

// 该结构体会带上SayHello方法,里面是业务代码

// 这样远程调用时就执行了业务代码了

type server struct {

// pb.go中自动生成的,是个空结构体

pb.UnimplementedGreeterServer

}

// 业务代码在此写,客户端远程调用SayHello时,

// 会执行这里的代码

func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {

// 打印请求参数

log.Printf(“Received: %v”, in.GetName())

// 实例化结构体HelloReply,作为返回值

return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil

}

func main() {

// 要监听的协议和端口

lis, err := net.Listen(“tcp”, port)

if err != nil {

log.Fatalf(“failed to listen: %v”, err)

}

// 实例化gRPC server结构体

s := grpc.NewServer()

// 服务注册

pb.RegisterGreeterServer(s, &server{})

log.Println(“开始监听,等待远程调用…”)

if err := s.Serve(lis); err != nil {

log.Fatalf(“failed to serve: %v”, err)

}

}

  • 以上就是gRPC服务的代码,与前几篇文章中的差不多,就不赘述了;

编写gRPC-Gateway服务端的代码

  • 开始编写gRPC-Gateway服务端代码,这是本文的重点所在,除了提供与前文一样的gRPC-Gateway服务,还提供了swagger的json文件服务,以及swagger的ui服务;

  • 新建文件夹$GOPATH/src/swaggerdemo/gateway;

  • 在新建的gateway文件夹下新增文件gateway.go,内容如下,有几处要注意的地方稍后会说明:

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 “swaggerdemo/pkg/ui/data/swagger”

gw “swaggerdemo”

)

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:9090”)

return http.ListenAndServe(“:9090”, mux)

}

func newGateway(ctx context.Context) (http.Handler, error) {

opts := []grpc.DialOption{grpc.WithInsecure()}

gwmux := runtime.NewServeMux()

if err := gw.RegisterGreeterHandlerFromEndpoint(ctx, gwmux, “:50051”, opts); err != nil {

return nil, err

}

return gwmux, nil

}

func serveSwaggerFile(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(“…/”, 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)

}

  • 22
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`io.grpc:protoc-gen-grpc-java:1.0.0:exe:${os.detected.classifier}` 是一个 Maven 坐标,用于使用 gRPC 的 Protocol Buffers 编译器插件来生成 gRPC 相关的 Java 代码。 这个坐标指定了以下部分: - `io.grpc` 是 Maven 组织 ID,表示该插件是由 gRPC 提供的。 - `protoc-gen-grpc-java` 是插件的名称,用于生成 gRPC 相关的 Java 代码。 - `1.0.0` 是插件的版本号,表示要使用的插件版本。 - `exe:${os.detected.classifier}` 指定了插件的文件类型和操作系统相关的后缀。 `${os.detected.classifier}` 是一个 Maven 变量,用于根据操作系统自动选择相应的插件文件。它会根据当前操作系统选择适当的文件后缀,例如在 Windows 上是 `.exe`,在 Linux 上是 `.linux-x86_64`。 通过在 Maven 项目的 `pom.xml` 文件中添加该依赖项,您可以在构建过程中自动下载并使用该插件来生成 gRPC 的 Java 代码。例如: ```xml <plugins> <plugin> <groupId>org.xolstice.maven.plugins</groupId> <artifactId>protobuf-maven-plugin</artifactId> <version>0.6.1</version> <configuration> <protocArtifact>com.google.protobuf:protoc:3.17.3:exe:${os.detected.classifier}</protocArtifact> <pluginId>grpc-java</pluginId> <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.0:exe:${os.detected.classifier}</pluginArtifact> </configuration> <executions> <execution> <goals> <goal>compile</goal> <goal>compile-custom</goal> </goals> </execution> </executions> </plugin> </plugins> ``` 这样配置后,您可以使用 `mvn compile` 命令来自动生成 gRPC 的 Java 代码。生成的代码将位于 `target/generated-sources/protobuf` 目录下。 请确保您的 Maven 项目中已经包含了正确的依赖项,并且配置文件中的版本号与您所需的版本一致。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值