教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 golang:REST接口

golang:REST接口

发布时间:2021-12-11   编辑:jiaochengji.com
教程集为您提供golang:REST接口等资源,欢迎您收藏本站,我们将为您提供最新的golang:REST接口资源

《GO语言高级编程》设计中案例,仅作为笔记进行收藏。gRPC服务一般用于集群内部通信,如果需要对外暴露服务一般会提供等价的REST接口。通过REST接口比较方便前端JavaScript和后端交互。开源社区中的grpcgateway项目就实现了将gRPC服务转为REST服务的能力。

grpc-gateway的工作原理如下图:

通过在Protobuf文件中添加路由相关的元信息,通过自定义的代码插件生成路由相关的处理代码,最终将REST请求转给更后端的gRPC服务处理。

<h3>1.环境准备</h3>

google/api/annotations.proto  采用 https://github.com/googleapis/googleapis 代替

go get -u github.com/grpc-ecosystem/grpc-gateway/tree/master/protoc-gen-grpc-gateway

go get -u github.com/grpc-ecosystem/grpc-gateway/tree/master/protoc-gen-swagger

go get -u github.com/swagger-api/swagger-ui

<h3>2.helloworld.proto</h3> <pre><code class="language-Go">syntax = "proto3"; package main; import "google/api/annotations.proto"; message StringMessage{ string value=1; } service RestService{ rpc Get(StringMessage) returns(StringMessage){ option(google.api.http)={ get:"/get/{value}" }; } rpc Post(StringMessage) returns(StringMessage){ option(google.api.http)={ post:"/post" body:"*" }; } }</code></pre> <h3>3.通过插件生成grpc-gateway的路由处理代码</h3> <pre><code class="language-Go">protoc --proto_path=. --proto_path=%GOPATH%github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis --go_out=plugins=grpc:. helloworld.proto protoc --proto_path=. --proto_path=%GOPATH%github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis --grpc-gateway_out=. helloworld.proto </code></pre> <h3>4.生成Swagger格式文件用于描述REST接口</h3> <pre><code class="language-Go">protoc --proto_path=. --proto_path=%GOPATH%github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis --swagger_out=. helloworld.proto</code></pre> <h3>5.main.go</h3> <pre><code class="language-Go">package main import ( "flag" "log" "net" "net/http" "github.com/golang/glog" "github.com/grpc-ecosystem/grpc-gateway/runtime" "golang.org/x/net/context" "google.golang.org/grpc" ) var ( port = ":5000" echoEndpoint=flag.String("echo_endpoint","localhost" port,"endpoint of YourService") ) type myGrpcServer struct {} func(s *myGrpcServer) Get(ctx context.Context,in *StringMessage)(*StringMessage,error){ return &StringMessage{Value: "Get:" in.Value},nil } func(s *myGrpcServer) Post(ctx context.Context,in *StringMessage)(*StringMessage,error){ return &StringMessage{Value: "Post: " in.Value},nil } func run() error{ ctx:=context.Background() ctx,cancel:=context.WithCancel(ctx) defer cancel() // 创建路由处理器 mux:=runtime.NewServeMux() opts:=[]grpc.DialOption{grpc.WithInsecure()} // 将RestService服务相关的REST接口转到后面的gRPC服务 err:=RegisterRestServiceHandlerFromEndpoint(ctx,mux,*echoEndpoint,opts) if err!=nil{ return err } return http.ListenAndServe(":8080",mux) } func main(){ flag.Parse() defer glog.Flush() go startGrpcServer() if err := run(); err != nil { glog.Fatal(err) } } func startGrpcServer(){ server:=grpc.NewServer() RegisterRestServiceServer(server,new(myGrpcServer)) lis,err:=net.Listen("tcp",port) if err != nil { log.Panicf("could not list on %s: %s", port, err) } if err := server.Serve(lis); err != nil { log.Panicf("grpc serve error: %s", err) } }</code></pre> <h3>6.执行</h3> <pre><code class="language-Go">curl localhost:8080/get/gopher // {"value":"Get: gopher"} curl localhost:8080/post -X POST --data '{"value":"grpc"}' // {"value":"Post: grpc"}</code></pre> <h3 style="text-indent:0px;">7.Swagger-ui</h3>

从 swagger-ui库中将 <span style="color:#f33b45;">dist</span> 文件夹移到自己的项目中,并更名为swagger。把swagger>>index.html中 url 进行更改。

<pre><code class="language-html"><script> window.onload = function() { // Begin Swagger UI call region const ui = SwaggerUIBundle({ url: "././helloworld.swagger.json", dom_id: '#swagger-ui', deepLinking: true, presets: [ SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset ], plugins: [ SwaggerUIBundle.plugins.DownloadUrl ], layout: "StandaloneLayout" }) // End Swagger UI call region window.ui = ui } </script></code></pre>

项目路径如下:

在main中添加代码如下:

<pre><code class="language-Go">func run() error{ ctx:=context.Background() ctx,cancel:=context.WithCancel(ctx) defer cancel() // 创建路由处理器 mux:=runtime.NewServeMux() opts:=[]grpc.DialOption{grpc.WithInsecure()} // 将RestService服务相关的REST接口转到后面的gRPC服务 err:=RegisterRestServiceHandlerFromEndpoint(ctx,mux,*echoEndpoint,opts) if err!=nil{ return err } http.Handle("/swagger/", http.StripPrefix("/swagger/", http.FileServer(http.Dir("swagger")))) return http.ListenAndServe(":8080",mux) }</code></pre> <h3 style="text-indent:0px;">8.项目运行</h3>

添加过 swagger 代码后,发现不出现效果,正常的 curl 测试还是可以的。

<pre><code class="language-Go">curl localhost:8080/get/gopher {"value":"Get: gopher"} curl localhost:8080/post -X POST --data '{"value":"grpc"}' {"value":"Post: grpc"}</code></pre>

经研究,http.ListenAndServe 采用默认 handle 时可以正常运行,但是接口无法访问。

<pre><code class="language-Go">func run() error{ ctx:=context.Background() ctx,cancel:=context.WithCancel(ctx) defer cancel() // 创建路由处理器 mux:=runtime.NewServeMux() opts:=[]grpc.DialOption{grpc.WithInsecure()} // 将RestService服务相关的REST接口转到后面的gRPC服务 err:=RegisterRestServiceHandlerFromEndpoint(ctx,mux,*echoEndpoint,opts) if err!=nil{ return err } http.Handle("/swagger/", http.StripPrefix("/swagger/", http.FileServer(http.Dir("swagger")))) return http.ListenAndServe(":8080",nil) }</code></pre>

<span style="color:#f33b45;">根据现在掌握的暂时无法解决,各位如果有解决的办法,请在评论区留言,谢过。</span>

 

 

 

 

 

 

 

到此这篇关于“golang:REST接口”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
golang:REST接口
接口隔离原则是什么?
php如何做接口
Go语言空接口类型(interface{})
Go语言接口interface
golang中接口查询
go 获取函数地址_Go语言基础--接口浅析
php中的interface是什么意思
go语言学习笔记(十三)——接口类型
2020-10-18Go语言接口

[关闭]
~ ~