Unlike FastAPI, Gin does not have OpenAPI integration built in. With FastAPI when you add a route, documentation is already generated. With Gin, this is not the case. But recently I integrated Swagger UI in one of my Go backends and I wanted to document that process.
- An already existing Gin server
You might consider Building a Book Store API in Golang With Gin if you are starting from scratch. I’ll be using the same book store and extending over it to integrate Swagger UI.
How Swagger works with Gin
The way Swagger works with other Go backend is not different they all have the same mechanism. But how does it really work and what do we have to really do?
Swagger uses the Go comment system which is very well integrated with documentation already as we know. We write comments in a pre-defined way, details of which we will see further ahead in the post. But mostly it is divided into 2 parts. The server itself and the routes.
Swagger has a CLI binary which when runs converts these comment documents into OpenAPI compliant documentation. The resultant file also includes OpenAPI server specs in JSON and YAML format.
Lastly, we route the generated content via a handler in our backend.
How do we do that? Let’s see.
Setup Swagger CLI
The prime repository you should keep under your pillow is https://github.com/swaggo/swag. Both in terms of CLI and documentation.
We’ll install a CLI application called
swag. Here’s how:
go get -u github.com/swaggo/swag/cmd/swag # 1.16 or newer go install github.com/swaggo/swag/cmd/[email protected]
The first command will download the dependencies to integrate in the server application.
The second one is where we install the CLI.
Now you should be able to run the swag command:
$ swag -h NAME: swag - Automatically generate RESTful API documentation with Swagger 2.0 for Go. USAGE: swag [global options] command [command options] [arguments...] VERSION: v1.8.1 COMMANDS: init, i Create docs.go fmt, f format swag comments help, h Shows a list of commands or help for one command GLOBAL OPTIONS: --help, -h show help (default: false) --version, -v print the version (default: false)
Documenting the Gin Server
When you look at Swagger UI documentation for any OpenAPI enabled website, you’d see something like this:
You might be familiar with the low half part of the UI. This is what Swagger docs are for i.e. to document the routes.
But before we deal with the lower 50% part I want you to notice in the above picture is the top 50% part. Right from the Swagger Petstore header to Find out more about the Swagger anchor link.
This part shows the metadata about the API server itself. In this section, we are going to build that part. You can find the code to start with here. We’ll be continuing on that code.
First of all, we need to go get the packages we need to work with:
go get -u github.com/swaggo/files go get -u github.com/swaggo/gin-swagger
Now after we have done that, let’s look at our main.go file. This is the
main.go at the moment:
Add a route for Swagger Docs
We add a new router in the main function:
The modified file would look like this:
ginSwagger.WrapHandler is a wrapper around
http.Handler, but for Gin.
This should be enough for testing. Let’s see how the docs render at
The good news is API documentation site is up. The bad news is it does not look like a normal API documentation site. What did we miss?
Generate swagger docs every time you modify doc string
Swagger documentation is stored in Go’s own docstring. We have a special syntax that we follow. More on that later. But first, let us learn how to generate docs.
$ swag init 2022/05/25 23:59:16 Generate swagger docs.... 2022/05/25 23:59:16 Generate general API Info, search dir:./ 2022/05/25 23:59:16 create docs.go at docs/docs.go 2022/05/25 23:59:16 create swagger.json at docs/swagger.json 2022/05/25 23:59:16 create swagger.yaml at docs/swagger.yaml
swag init every time we update docs for our API. This generates 3 files inside a sub directory called
$ tree docs docs ├── docs.go ├── swagger.json └── swagger.yaml 0 directories, 3 files
swagger.yaml are the actual specification which you can upload to services like AWS API Gateway and similar services.
docs.go is a glue code that we need to import into our server.
Let us now import the documentation to our main.go.
As you can see we have imported
docs the module by giving the full path of the module. We also have to prepend this import using
_ because it is not explicitly used in main.go file.
You might also have noticed
// @title Gingo Bookstore API line. Please note its position as this is important. It is just above the
main() func. Also
@title is not random here. It is one of the keywords which is documented under General API Info. We’ll see more of these as we go, but for now, let’s regenerate our docs and review the API docs.
Looks like we are getting somewhere. :D
Add General API Info to Gin API Server
@title annotation in the last section. It is used to set the title for the API server. But it is not the only annotation available. There is a wide array of annotation in Swagger. You can find them in use in real life here.
I’m going to use some of them to construct metadata on my doc site.
// @title Gin Book Service // @version 1.0 // @description A book management service API in Go using Gin framework. // @termsOfService https://tos.santoshk.dev // @contact.name Santosh Kumar // @contact.url https://twitter.com/sntshk // @contact.email [email protected] // @license.name Apache 2.0 // @license.url http://www.apache.org/licenses/LICENSE-2.0.html // @host localhost:8080 // @BasePath /api/v1
- Re-run the server.
- Check for update:
That’s some metadata in there.
You might also have noticed that the API spec inside docs/ directory has changed. For example, here is the
swagger.yaml file from the
Now it’s time to add docs for API endpoints.
Add API Operation Info to API Endpoints
Just like General API Info for the main server, there also is API Operation for individual routes/endpoints handlers.
They are more diverse than what I’m going to use here. The ones I’m going to use are just a subset of them. If you want to check out some real examples, you can find them here on each of the route handlers.
Here is modified
- Re-run the server.
- Check for updates:
And here is the updated
Notice the new
paths section added. It is for models and the endpoints respectively.
Bonus: Router Group for /api/v1
It is always a good idea to prepend your routes with
v1 bit has a logic behind it. It is for the time when you have to introduce a breaking change which is not backward compatible. Maybe the input or the output has changes that might break millions of dependent client.
In these situations, you increment the version to something like
api/v2 and let the older API server serve old from the old handler.
Right now all of the routes in gingo server start with
/book. We are going to change that.
Here is the modified
Here we use
router.Group to create a group with a path of
/api/v1. We then move all the route definitions into the group and surround it with braces. That is how we create a path route in Gin.
API documentation is an essential part of API documentation. Instead of documenting the endpoints anywhere else, we can document the routes right in the code. That way we only have 1 single source of truth. No need to maintain code and documentation separately. In turn, we get always up-to-date documentation.
Every backend server has some sort of support for Swagger UI. I have covered the basics for Gin, but if you use any other framework, I encourage you to look for your own framework.