I’ve previously written an Article on generating OpenAPI (Swagger) spec automatically within Golang. It’s the most popular article on this blog since lots of developers are searching for it. In it, I mentioned that in order to serve the swagger.json with SwaggerUI, a Docker instance is required that will serve SwaggerUI. There is an easier way to implement it, and this article will demonstrate how to do it with net/http, Gin and Echo.
Comming from SpringBoot, I was used to having a SwaggerUI served automatically once the dependency for it was added. With few annotations, visiting /swagger-ui would provide a SwaggerUI with all endpoints listed.
However, in Go, not everything is as easy as that. Generating Swagger.json is bit troublesome and needs a special guide, and then there is serving it on SwaggerUI.
Downloading SwaggerUI files
SwaggerUI can be downloaded from their GitHub Repo. Once downloaded, place the content of dist
folder somewhere in your Go project. For example, swaggerui.
After that, move swagger.json file to swaggerui folder, and inside index.html change url to ./swagger.json (url: "./swagger.json"
).
Serve using net/http
fs := http.FileServer(http.Dir("./swaggerui"))
http.Handle("/swaggerui/", http.StripPrefix("/swaggerui/", fs))
Serve using Gorilla Mux (commit)
fs := http.FileServer(http.Dir("./swaggerui/"))
r.PathPrefix("/swaggerui/").Handler(http.StripPrefix("/swaggerui/", fs))
Serve using Echo (commit)
r.Static("/swaggerui", "cmd/api/swaggerui")
Serve using Gin (commit)
r.Static("/swaggerui/", "cmd/api/swaggerui")
End result:
A better approach
One of the greatest advantages of Go is that compiles all the source code into a single binary. If you follow the approach of putting all html/css/js files into your project folder, those won’t be compiled into Go’s binary. You’ll have to deploy swaggerui
folder somewhere next to the Go binary and then set the correct path.
Using a 3rd part library, swaggerui can be compiled together with rest of the source code during build. For this, I’m using Statik, but there are plenty of alternatives such as Packr.
With statik, you first run their command to build a go file from your static files:
statik -src=/Users/ribice/go/src/github.com/ribice/golang-swaggerui-example/cmd/swaggerui
A new folder statik
will be created, and inside a single go file, static.go
. It’s unreadable, so don’t bother with that.
Afterwards, you’ll need the following:
_ "github.com/ribice/golang-swaggerui-example/cmd/swaggerui" // path to generated statik.go
statikFS, err := fs.New()
if err != nil {
panic(err)
}
staticServer := http.FileServer(statikFS)
Static server is a HTTP handle, so you can serve it easily using Mux or net/http
sh := http.StripPrefix("/swaggerui/", staticServer)
router.PathPrefix("/swaggerui/").Handler(sh)
An example commit is available HERE.
With Echo and Gin, you have to wrap the http handler into their custom ones. For example:
sh := http.StripPrefix("/swaggerui/", staticServer)
eh := echo.WrapHandler(sh)
e.GET("/swaggerui", eh)