教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 【Golang】无敌好用GRPC接口测试工具的使用-Swagger

【Golang】无敌好用GRPC接口测试工具的使用-Swagger

发布时间:2021-12-09   编辑:jiaochengji.com
教程集为您提供【Golang】无敌好用GRPC接口测试工具的使用-Swagger等资源,欢迎您收藏本站,我们将为您提供最新的【Golang】无敌好用GRPC接口测试工具的使用-Swagger资源
<h1>《本文不涉及原理,纯使用操作》</h1>

操作系统:Ubuntu18.04 amd64,我打包了的是我自己的平台的可执行程序,其他平台请自行使用源码编译相关工具。

开始之前,先安装protoc相关工具和环境,具体百度(我默认你肯定已经装好了,能打出protoc命令而不报出no command found)。再去下载我的模板项目,并下载相关依赖和必须工具,边下边看我应该都打包好了。缺了文件或者有问题请及时通知我,谢谢!

我的示例工程:https://gitee.com/wzj2018/grpc-example,github一言难尽,用了gitee。理论上里面的可执行程序可以直接体验。

用到的工具源码:https://github.com/grpc-ecosystem ,你需要里面的go-grpc-middleware和grpc-gateway。grpc-gateway里面有我们需要的 annotations.proto。

打包的工具们:https://download.csdn.net/download/m0_38059938/12537541。解压后最好放到GOPATH/bin里面。GOPATH/bin也要添加到系统PATH中。

先通过效果介绍一下。。。

假设做了几十个rpc接口,那么你想测试rpc调用,你想一个个请求手写吗?显然不想。现在就有这么个工具,可以只需要写少量代码,即可自动化生成可视化接口调用测试工具:

<h1></h1>

下面就进行实际操作。

 

<h1>想直接试试的可以现在就打开下载的工程示例自己摸索操作了,里面也有我已经编译好的程序,windows 和 linux都有。</h1>

 

<h1>1、准备你的*.proto协议文件。</h1> <pre><code>syntax = "proto3"; //天气请求查询服务接口测试工具 package weather; option optimize_for = CODE_SIZE; //这个引入关键 import "google/api/annotations.proto"; service Weather { rpc QueryCity(QueryType) returns (ResponseType) { //这个option也很关键,它指定了swagger api的http请求地址 option (google.api.http) = { post: "/v1/weather/city" body:"*" }; } rpc QueryRegion(QueryType) returns (ResponseType) { //这个option也很关键,它指定了swagger api的http请求地址 option (google.api.http) = { get: "/v1/weather/region" }; } } message QueryType { string Name = 1; uint32 Code = 2; } message ResponseType { string Result = 1; uint32 Status = 2; } </code></pre> <h1>2、MakeFile</h1>

    makefile放在和proto文件一个目录下。如果你执行make报错了,可以根据报的错分析原因,最常见的就是找不到命令,这个多半是我打包的工具你没有妥善部署。

    注意了,尽管我makefile里面是写的*.proto,意味着他会处理所有这个目录下的proto文件。但是,如果你真的有多个proto文件,请尽量合并成一个proto来进行测试。当然多个proto是可以的,只不过生成的代码需要人为修改,因为会出现函数的重复定义。相信读者你实在是需要了,可以稍微花点功夫处理下,我不再赘述了。

    make之后,会在当前工作目录下生成若干文件:多个go代码文件,一个swagger.json文件。go代码文件中就有我们可以直接使用的已经写好的grpc调用函数。哪个json是接口说明文档,把它丢到gateway/swagger中,重命名为swagger.json,即可再浏览器中访问。

<pre><code> #这个记得改了 export GOPATH=/mnt/hgfs/GoPath #注意,-I 表示以来的 *.proto 的搜索路径,我的是放在 ${GOPATH}/src下面,还有 #${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis目录下面,根据你的情况修改路径。 #当然。还有当前目录 “.” #其他的不改。 all: protoc -I/usr/local/include -I. \ -I${GOPATH}/src \ --go_out=plugins=grpc:. \ *.proto protoc -I/usr/local/include -I. \ -I${GOPATH}/src \ -I${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ --grpc-gateway_out=logtostderr=true:. \ *.proto protoc -I/usr/local/include -I. \ -I${GOPATH}/src \ -I${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ --swagger_out=allow_delete_body=true,allow_merge=true,logtostderr=true:. \ *.proto protoc -I/usr/local/include -I. \ --letmegrpc_out=. \ --proto_path=${GOPATH}/src/ \ *.proto</code></pre> <h1>3、编写一个模拟的server service</h1> <pre><code class="language-Go">package main import ( "another/pb" "context" "math/rand" ) //随便实现一个最简的server service type WeatherServer struct { } //rpc1模拟内容 func (w *WeatherServer) QueryRegion(ctx context.Context, queryType *weather.QueryType) (*weather.ResponseType, error) { return &weather.ResponseType{ Result: "Great weather, The REGION you're querying:" queryType.Name, Status: rand.Uint32(), }, nil } //rpc2模拟内容 func (w *WeatherServer) QueryCity(ctx context.Context, queryType *weather.QueryType) (*weather.ResponseType, error) { return &weather.ResponseType{ Result: "Great weather, although I just made it up! The city you're querying:" queryType.Name, Status: rand.Uint32(), }, nil } </code></pre> <h1>4、编写server主程序</h1> <pre><code class="language-Go">//go:generate protoc --go_out=plugins=grpc:../gp -I ../gp ../gp/weather.proto package main import ( smart "another/pb" "context" "flag" "fmt" go_grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" "github.com/grpc-ecosystem/go-grpc-middleware/auth" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" "log" "net" ) const Token = "a" const Authority = "a" func main() { port := flag.Int("p", 8787, "listen port") flag.Parse() lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port)) if err != nil { log.Fatalf("failed to listen: %v", err) } // 新建grpc服务,并传入拦截器进行认证检查 grpcServer := grpc.NewServer( grpc.StreamInterceptor(go_grpc_middleware.ChainStreamServer( grpc_auth.StreamServerInterceptor(auth), )), grpc.UnaryInterceptor(go_grpc_middleware.ChainUnaryServer( grpc_auth.UnaryServerInterceptor(auth), )), ) //scannerIns := &ScannerServiceInstance{} //sealerIns := &SealerInstance{} //pcrIns := &PCRInstance{} weatherInstance := &WeatherServer{} // 注册grpc实例 //smart.RegisterScannerServiceServer(grpcServer, scannerIns) //smart.RegisterSealerServiceServer(grpcServer, sealerIns) //smart.RegisterMetalBathServiceServer(grpcServer, pcrIns) smart.RegisterWeatherServer(grpcServer, weatherInstance) log.Printf("server start at %v", *port) _ = grpcServer.Serve(lis) } // auth 对传入的metadata中的:authority内容进行判断,失败后再对token进行判断 func auth(ctx context.Context) (ctx1 context.Context, err error) { md, ok := metadata.FromIncomingContext(ctx) if !ok { err = status.Error(codes.Unauthenticated, "token信息不存在") return } if authority, exists := md[":authority"]; exists && len(authority) > 0 { if authority[0] == Authority { ctx1 = ctx return } } tokenMD := md["token"] if tokenMD == nil || len(tokenMD) < 1 { err = status.Error(codes.Unauthenticated, "token信息不存在") return } if err = tokenValidate(tokenMD[0]); err != nil { err = status.Error(codes.Unauthenticated, err.Error()) return } ctx1 = ctx return } func tokenValidate(token string) (err error) { if token != Token { err = fmt.Errorf("token认证错误") return } return } </code></pre> <h1>5、编写gateway程序</h1>

    客户端内容比较呆,这里不再阐述,详情可以看我的工程实例里面。但事实上,gateway又何尝不是一个clinet?

<pre><code class="language-Go">package main import ( weather "another/pb" "context" "github.com/grpc-ecosystem/grpc-gateway/runtime" "google.golang.org/grpc" "io/ioutil" "log" "net/http" "os" ) func run(IP string) error { ctx := context.Background() ctx, cancel := context.WithCancel(ctx) defer cancel() gwmux := runtime.NewServeMux() var opts []grpc.DialOption opts = append(opts, grpc.WithInsecure()) opts = append(opts, grpc.WithAuthority("a")) //*****************以下是需要修改的地方******************** //每新建一个rpc service,就要在这里给新的service注册一下 //这里事例了三个service的注册:ScannerService, MetalBathService, SealerService(名字为对应proto中的service name) //make命令生成的注册函数命名方式固定为:RegisterXXXXXXXHandlerFromEndpoint(...) //err := pb.RegisterScannerServiceHandlerFromEndpoint(ctx, gwmux, IP, opts) //if err != nil { // return err //} // //err = pb.RegisterMetalBathServiceHandlerFromEndpoint(ctx, gwmux, IP, opts) //if err != nil { // return err //} // //err = pb.RegisterSealerServiceHandlerFromEndpoint(ctx, gwmux, IP, opts) //if err != nil { // return err //} err := weather.RegisterWeatherHandlerFromEndpoint(ctx, gwmux, IP, opts) if err != nil { return err } //示例: // err = pb.RegisterNewXXXServiceHandlerFromEndpoint(ctx, gwmux, IP, opts) // if err != nil { // return err // } //****************以上是需要修改的地方*********************** mux := http.NewServeMux() mux.Handle("/", gwmux) bytes, _ := ioutil.ReadFile("./swagger/favicon.ico") mux.Handle("/swagger/", http.FileServer(http.Dir("."))) mux.HandleFunc("/favicon.ico", func(writer http.ResponseWriter, request *http.Request) { _, err = writer.Write(bytes) if err != nil { _, _ = writer.Write([]byte(err.Error())) } }) //指定gateway swagger的监听端口,目前是localhost:8888 log.Println("Gateway started, visit localhost:8888/swagger in your Chrome browser.") return http.ListenAndServe(":8888", mux) } func main() { log.SetFlags(log.Lshortfile|log.Ltime) if err := run(os.Args[1]); err != nil { log.Fatal(err) } } </code></pre> <h1>最后</h1>

我把所有内容都尽量精简并浓缩到了一个main.go中,理论上现在只需要编译通过就行了。

总结:
1、将填写了SWAGGER API option参数的 *.proto 放到 ./pb/ 目录下
2、/pb/ 目录下,执行make
3、/pb/ 目录下,生成.go代码若干以及一个apidocs.swagger.json,将它复制到 /gateway/swagger目录下,替换掉那里的swagger.json
4、修改 /gateway/main.go 中的
1、run()函数中的需要修改部分
2、main()函数中的目标server address
5、在 /gateway/ 目录下执行 go build 命令编译,得到可执行程序,运行即可在run()函数中的监听端口访问

到此这篇关于“【Golang】无敌好用GRPC接口测试工具的使用-Swagger”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
【Golang】无敌好用GRPC接口测试工具的使用-Swagger
golang:REST接口
Golang基础第五篇——golang的gRPC
使用 Go 添加文档
Golang 微服务 - 01 环境和工具
golang http client 使用gzip_一次gRPC使用不当导致goroutine泄漏排查记录
golang微服务框架对比_Golang 中的微服务 - 第一部分
Windows10 golang gRPC环境搭建
Golang 微服务教程(一)
用cmd运行python文件_怎么用cmd运行python文件

[关闭]
~ ~