Serve SwaggerUI within your Golang application

Emir Ribic
3 min readJun 11, 2018

--

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.

Read about Goch — Self hosted live-chat built with Go, NATS, Redis and Webscockets

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)

sh := http.StripPrefix("/swaggerui/", http.FileServer(http.Dir("./swaggerui/")))
r.PathPrefix("/swaggerui/").Handler(sh)

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 it all the source code can be compiled into a single binary. If you follow the approach of putting swaggerui html/css/js files in a separate folder, they won’t be compiled into a Go binary. You’ll have to deploy swaggerui folder somewhere next to the Go binary and then set the correct path.

To achieve this a third party dependency is needed. I’m using Statik, but plenty of alternatives exist 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)

--

--

Responses (7)