GRPC+GRPC Gateway Practice three swagger learn about

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Swagger, look.

In the previous section, we completed a service-side support at the same time Rpc and RESTful Api after you thought you were done, the results suddenly found to write Api documents and front-end colleague Docking = = ...

You're wondering if there are any components that can automate the generation of Api documents to solve this problem, and then you find out Swagger and get to know them together!

Introduced

Swagger

SwaggerIs the world's largest OpenAPI normative (OAS) API development tool framework that supports the development of the entire API lifecycle from design and documentation to testing and deployment

Swaggeris currently one of the most popular RESTful Api document generation tools, mainly for the following reasons

    • Cross-platform, cross-language support
    • A strong community
    • Eco-Circle Swagger Tools (Swagger Editor, Swagger Codegen, Swagger UI ... )
    • Powerful console

grpc-gatewayIt also supportsSwagger

OpenAPISpecification

OpenAPIThe specification is Linux a project of the foundation that attempts to standardize the RESTful service development process by defining a language that describes the API format or API definition. OpenAPIThe specification helps us to describe the basic information of an API, such as:

    • General description of the API
    • Available paths (/Resources)
    • Available actions on each path (get/submit ...) )
    • Input/output format for each operation

Currently the V2.0 version of the OPENAPI specification (i.e. the SWAGGERV2.0 specification) has been released and open source on GitHub. The document is very well written and has a clear structure for easy access at any time.

Note: OpenAPI the introduction of the specification is quoted from the original

Use

Swaggerthe generated description file

first , we need to check whether the protoc-gen-swagger executable file is included under $gobin

If it does not exist, it needs to be executed:

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

After the execution has been completed, you can $GOPATH/bin find the execution file below and move it to the $GOBIN next

second , go back $GOPATH/src/grpc-hello-world/proto and execute the order.

protoc -I/usr/local/include -I. -I$GOPATH/src/grpc-hello-world/proto/google/api --swagger_out=logtostderr=true:. ./hello.proto

After successful execution ls you can see the hello.swagger.json file

Download Swagger UI file

SwaggerProviding a visual API management platform is the swagger UI

We download its source code and dist copy all the files in its directory to our project. $GOPATH/src/grpc-hello-world/third_party/swagger-ui

will be Swagger UI converted to Go source code

The conversion tool we use here is Go-bindata

It supports the conversion of any file to manageable Go source code. Used to embed binary data into the Go program. And you can choose to compress the file data before converting the file data to the original byte slice

Installation

go get -u github.com/jteeuwen/go-bindata/...

When you are finished, $GOPATH/bin go-bindata Move down to the $GOBIN bottom

Transformation

Create a new directory under the project pkg/ui/data/swagger , go back $GOPATH/src/grpc-hello-world/third_party/swagger-ui , execute the command

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

Check

Go back to pkg/ui/data/swagger the table of contents to check if datafile.go files exist

Swagger UIFile server (external service)

In this step, we need to use the matching Go-bindata-assetfs

It can use the go-bindata generated Swagger UI Go code, combined with net/http external services

Installation

go get github.com/elazarl/go-bindata-assetfs/...

Write

Through analysis, we learned that the generated file provides a assetFS function that returns an embedded file that is encapsulated http.Filesystem and can be used to provide a HTTP service

So let's write Swagger UI the code, mostly two parts, one is swagger.json , the other is swagger-ui the response

Serveswaggerfile

Reference Packages strings ,path

func serveSwaggerFile(w http.ResponseWriter, r *http.Request) {      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("proto", p)    log.Printf("Serving swagger-file: %s", p)    http.ServeFile(w, r, p)}

In the function, we use r.URL.Path the path suffix to judge

Main swagger.json file access support (provided https://127.0.0.1:50052/swagger/hello.swagger.json access)

Serveswaggerui

Reference Packages github.com/elazarl/go-bindata-assetfs ,grpc-hello-world/pkg/ui/data/swagger

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))}

In the function, we use the Go-bindata-assetfs to dispatch the previously generated datafile.go service, which is combined net/http to provide swagger-ui services externally.

Combine

After we have finished the function, we find that it path.Join("proto", p) is written to the dead parameter, so obviously it is wrong, we should export it as an external parameter, then we will finally retrofit

First we are server.go adding global variables to the package SwaggerDir , modifying the cmd/server.go file:

Package Cmdimport ("Log" "Github.com/spf13/cobra" "Grpc-hello-world/server") var servercmd = &cobra. command{use: "Server", Short: "Run the Grpc hello-world server", Run:func (cmd *cobra. Command, args []string] {defer func () {if err: = Recover (); Err! = nil {log. PRINTLN ("Recover Error:%v", Err)}} () server. Run ()},}func init () {servercmd.flags (). Stringvarp (&server. ServerPort, "Port", "P", "50052", "Server Port") servercmd.flags (). Stringvarp (&server. Certpempath, "Cert-pem", "", "./conf/certs/server.pem", "Cert-pem Path") servercmd.flags (). Stringvarp (&server. Certkeypath, "Cert-key", "", "./conf/certs/server.key", "Cert-key Path") servercmd.flags (). Stringvarp (&server. Certservername, "Cert-server-name", "", "GRPC server name", "Server ' hostname") servercmd.flags (). Stringvarp (&server. Swaggerdir, "Swagger-dir", "", "Proto", "Path to the directory which COntains swagger Definitions ") Rootcmd.addcommand (Servercmd)} 

Modified path.Join("proto", p) to path.Join(SwaggerDir, p) , so that our swagger.json file path can be modified according to external conditions

Final server.go file content:

Package Serverimport ("Crypto/tls" "Net" "Net/http" "Log" "Strings" "Path" Golang.org/x/net/context    "" Google.golang.org/grpc "" Google.golang.org/grpc/credentials "" Github.com/grpc-ecosystem/grpc-gateway/runtime " "Github.com/elazarl/go-bindata-assetfs" PB "Grpc-hello-world/proto" "Grpc-hello-world/pkg/util" "Grpc-hell O-world/pkg/ui/data/swagger ") var (serverport string Certservername string Certpempath string Certkeypath stri Ng Swaggerdir string EndPoint string Tlsconfig *tls. Config) Func Run (err error) {EndPoint = ":" + serverport tlsconfig = util. Gettlsconfig (Certpempath, Certkeypath) conn, err: = Net. Listen ("TCP", EndPoint) if err! = Nil {log. Printf ("TCP Listen err:%v\n", Err)} SRV: = NewServer (conn) log. Printf ("Grpc and HTTPS listen on:%s\n", serverport) if Err = srv. Serve (util. Newtlslistener (conn, tlsconfig)); Err! = Nil {log.    Printf ("Listenandserve:%v\n", err)}Return err} func newserver (conn net. Listener) (*http. Server) {grpcserver: = Newgrpc () Gwmux, err: = Newgateway () if err! = Nil {panic (err)} MUX: = Htt P.newservemux () Mux. Handle ("/", Gwmux) mux. Handlefunc ("/swagger/", Serveswaggerfile) Serveswaggerui (MUX) return &http. server{Addr:endpoint, Handler:util. Grpchandlerfunc (Grpcserver, MUX), Tlsconfig:tlsconfig,}}func newgrpc () *grpc. Server {creds, err: = credentials. Newservertlsfromfile (Certpempath, Certkeypath) if err! = Nil {panic (err)} opts: = []grpc. serveroption{Grpc. Creds (creds),} server: = Grpc.    NewServer (opts ...) Pb. Registerhelloworldserver (server, Newhelloservice ()) return Server}func Newgateway () (HTTP. Handler, error) {CTX: = context. Background () dcreds, err: = credentials. Newclienttlsfromfile (Certpempath, certservername) if err! = Nil {return nil, err} dopts: = []grpc. Dialoption{grpc. WithtrAnsportcredentials (Dcreds)} Gwmux: = Runtime. Newservemux () If err: = PB. Registerhelloworldhandlerfromendpoint (CTX, Gwmux, EndPoint, dopts); Err! = Nil {return nil, err} return Gwmux, Nil}func serveswaggerfile (w http. Responsewriter, R *http. Request) {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 (Swaggerdir, 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))}

Test

Access the path to https://127.0.0.1:50052/swagger/hello.swagger.json see if the output is content hello.swagger.json , for example:

Access path https://127.0.0.1:50052/swagger-ui/ , view content

Summary

This chapter is now complete, Swagger and its ecological circle is very rich, interested in the study of small partners can go to their official website to seriously study

And the current level of completion to meet the needs of the daily work, can be more automated RESTful Api document generation, complete and interface docking

Reference

Sample code

    • Grpc-hello-world
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.