Why Swagger?
When writing API docs, there are two approaches you can take:
- Write them in a markdown file, update that everytime something changes (see Monzo’s API docs).
- Auto-generate them directly from your code.
We’re going to take a look at one way of achieving option 2. Auto-generating docs enforces thorough documentation in the code itself, while making your API docs super maintainable by removing the risk of our docs getting out-of-sync with our backend.
Swagger is the most widely used open-source tool that let’s you do 2. After Swagger handles the auto-generation of API docs, you can pass that output to another tool to lay on some HTML and CSS to make it beautiful (tools include Swagger UI, Slate)
Choosing a library
There are two libraries available for using Swagger with Go:
Long story short, swag is simpler and go-swagger is more powerful and more widely used. You can read-up on some more discussion of what’s best here, here, and here.
We went for go-swagger, as we’d like as much flexibility with the API docs as possible and value the increased engagement with the project.
Let’s generate some docs for our new doggies API…
We’re going to walk through making a super-simple API and generating some docs with Swagger 💪
Our project is going to look like this:
Doggies API: Setup the project
First, we’re going to create files needed for a super-simple Go server:
We’ll be using the external library gorilla/mux to serve our API, so go ahead and install that with go get -u github.com/gorilla/mux. Then make sure we’ve initialised our go modules with go mod init.
New, we need an endpoint so we have something to generate.
Doggies API: Create an endpoint
Add the following to main.go and api.go respectively.
You should now be able to run go run main/main.go to start your server without any errors.
Great! Now we’re ready to start generating our docs.
Doggies API: Swagger setup
First, let’s create a docs package to store the comments and structs required by Swagger.
We’ll also have to import it in main.go, so that the docs package is built by Go (without that import, there’d be no entry point for our docs package).
Now let’s fill in our docs package.
We’re going to add the following to docs.go:
Notice how it’s all comments except for the package name on the last line. This is intentional. Swagger will interpret these comments as metadata for our API. You can read more about it in Swagger’s own docs.
The main thing we’ve defined here is the name of our service, after Package classification, and then a description of our service right after that.
Now, we’ll document our dogs endpoint by adding a new file in our docs package, dogs.go.
Here’s how we’ll do it:
There’s a few things to note here:
- The part following swagger:route defines the properties of our endpoint. It’s a POST request at /dog. It has a dog-tag, which is used to group similar endpoints together in our docs. And it has an idDog, which corresponds to the id above dogParamsWrapper a few lines below.
- We then have a description “Dog creates a new dog.”, and a list of responses, each with an id, in this case only dogSuccessResponse, which corresponds to the id above dogResponseWrapper.
- The // Dog creates a new dog. text will appear as the description of our request body
- In the two types below, we use // in:body to point to the structs in our api package that make up the request and response parameters.
We’re set! Let’s generate those docs ✨
Generate our docs
First, we’ll have to download the swagger command, which let’s us generate and play with our new docs:
Generate and serve our yaml file
Run the first command to generate the swagger.yaml file that will be the source of truth for our docs and the second command serve our docs locally💥
You’ll never need to touch the swagger.yaml file. Instead, you can regenerate it by updating the comments in docs.go and the comments around your API endpoints before running swagger generate once more.
You should have something that looks like this:
Conclusion
We’re done! Enjoy your shiny new API docs 👋
Why Swagger?
When writing API docs, there are two approaches you can take:
- Write them in a markdown file, update that everytime something changes (see Monzo’s API docs).
- Auto-generate them directly from your code.
We’re going to take a look at one way of achieving option 2. Auto-generating docs enforces thorough documentation in the code itself, while making your API docs super maintainable by removing the risk of our docs getting out-of-sync with our backend.
Swagger is the most widely used open-source tool that let’s you do 2. After Swagger handles the auto-generation of API docs, you can pass that output to another tool to lay on some HTML and CSS to make it beautiful (tools include Swagger UI, Slate)
Choosing a library
There are two libraries available for using Swagger with Go:
Long story short, swag is simpler and go-swagger is more powerful and more widely used. You can read-up on some more discussion of what’s best here, here, and here.
We went for go-swagger, as we’d like as much flexibility with the API docs as possible and value the increased engagement with the project.
Let’s generate some docs for our new doggies API…
We’re going to walk through making a super-simple API and generating some docs with Swagger 💪
Our project is going to look like this:
Doggies API: Setup the project
First, we’re going to create files needed for a super-simple Go server:
We’ll be using the external library gorilla/mux to serve our API, so go ahead and install that with go get -u github.com/gorilla/mux. Then make sure we’ve initialised our go modules with go mod init.
New, we need an endpoint so we have something to generate.
Doggies API: Create an endpoint
Add the following to main.go and api.go respectively.
You should now be able to run go run main/main.go to start your server without any errors.
Great! Now we’re ready to start generating our docs.
Doggies API: Swagger setup
First, let’s create a docs package to store the comments and structs required by Swagger.
We’ll also have to import it in main.go, so that the docs package is built by Go (without that import, there’d be no entry point for our docs package).
Now let’s fill in our docs package.
We’re going to add the following to docs.go:
Notice how it’s all comments except for the package name on the last line. This is intentional. Swagger will interpret these comments as metadata for our API. You can read more about it in Swagger’s own docs.
The main thing we’ve defined here is the name of our service, after Package classification, and then a description of our service right after that.
Now, we’ll document our dogs endpoint by adding a new file in our docs package, dogs.go.
Here’s how we’ll do it:
There’s a few things to note here:
- The part following swagger:route defines the properties of our endpoint. It’s a POST request at /dog. It has a dog-tag, which is used to group similar endpoints together in our docs. And it has an idDog, which corresponds to the id above dogParamsWrapper a few lines below.
- We then have a description “Dog creates a new dog.”, and a list of responses, each with an id, in this case only dogSuccessResponse, which corresponds to the id above dogResponseWrapper.
- The // Dog creates a new dog. text will appear as the description of our request body
- In the two types below, we use // in:body to point to the structs in our api package that make up the request and response parameters.
We’re set! Let’s generate those docs ✨
Generate our docs
First, we’ll have to download the swagger command, which let’s us generate and play with our new docs:
Generate and serve our yaml file
Run the first command to generate the swagger.yaml file that will be the source of truth for our docs and the second command serve our docs locally💥
You’ll never need to touch the swagger.yaml file. Instead, you can regenerate it by updating the comments in docs.go and the comments around your API endpoints before running swagger generate once more.
You should have something that looks like this:
Conclusion
We’re done! Enjoy your shiny new API docs 👋