Documenting your Golang APIs with Swagger
In the realm of API development, clear and comprehensive documentation is crucial for ensuring seamless integration and usability. Swagger, an open-source framework, excels at automating the generation of interactive and up-to-date API documentation. For developers working with Go, integrating Swagger can significantly enhance the clarity and accessibility of your APIs. This article will delve into the benefits of using Swagger with Go and provide a straightforward guide to getting started, helping you create well-documented APIs that are easy for developers to understand and use.
Swagger provides a comprehensive ecosystem to help design, build, document, and consume RESTful web services. By integrating Swagger with your Go APIs, you can automatically generate interactive and up-to-date API documentation that enhances clarity and usability, fostering better communication between your development team and API consumers.
To document our APIs, we will use the swaggo/swag package. This package converts Go annotations to Swagger Documentation 2.0.
Setting Up
To install Swag, you can use the following Go command:
go install github.com/swaggo/swag/cmd/swag@latest
Alternatively you can run the docker image using:
docker run --rm -v $(pwd):/code ghcr.io/swaggo/swag:latest
Navigate to the root directory of your project where your main.go file is located. Run the swag init command to parse your comments and generate the necessary documentation files (specifically, the docs folder and the docs/docs.go file).
If your main.go file is in a subdirectory (e.g., cmd), specify the path using the -g flag:
swag init -g cmd/main.go
If main.go is in the root directory, simply run:
swag init
If swag init
does not work, try this method.
The example API in this guide is built using the Gin Web Framework. To integrate Swag with other frameworks, refer to the documentation available on the Swag GitHub page. For detailed instructions and framework-specific configurations, consult the respective sections in the Swag documentation.
API Annotations
In the context of Swagger and tools like swaggo/swag, API annotations are special comments within your code that describe your API endpoints. These annotations facilitate the automatic generation of your API documentation. To enable Swagger to generate documentation, annotations should be added in two primary locations:
- Our
main.go
file, and - Before each controller function
The main.go
file
In the main.go file, general annotations are added. These annotations typically include:
- API Host URL
- API Base Path
- Documentation Title
- Documentation Version
- Documentation Description
- Your Name and Contact Details
- Security Definitions (for endpoints requiring authorization)
Below is an example of how to annotate your main.go file:
package main import ( "log" "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" "path-to-your-module/models" "path-to-your-module/routes" "path-to-your-module/internal/database" "path-to-your-module/pkg/config" // Install these packages swaggerFiles "github.com/swaggo/files" ginSwagger "github.com/swaggo/gin-swagger" // Import the docs package generated by swag _ "path-to-your-module/docs" ) // @title Your-API-Name // @version Your-API-Version // @description Your-API-Description // @termsOfService http://swagger.io/terms/ // @contact.name Your-Name // @contact.url Your-Website // @contact.email Your-Email // @license.name Apache 2.0 // @license.url http://www.apache.org/licenses/LICENSE-2.0.html // @host Your-API-Host // @BasePath Your-API-BasePath // @securityDefinitions.apikey Your-Security-KeyName // @in header // @name Authorization // @externalDocs.description OpenAPI // @externalDocs.url https://swagger.io/resources/open-api/ func init() { database.ConnectToDB() } func main() { //Run AutoMigrations for your models err := database.DB.AutoMigrate(&models.Model{}) if err != nil { log.Fatal(err) } r := gin.Default() r.Use(cors.Default()) v1 := r.Group("/api/v1") { routes.AuthRoutes(v1) } // Add this endpoint to access your swagger documentation r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) r.Run(config.ENV.ServerPort) }
Annotations on Controller Functions
In addition to the main file, annotations should be placed before each controller function. These annotations describe the specifics of each endpoint, such as:
- HTTP method (GET, POST, PUT, DELETE)
- Endpoint path
- Summary of the endpoint's functionality
- Parameters (query, path, body)
- Response types and descriptions
- Security requirements (if any)
By systematically adding these annotations, you ensure that your API documentation is thorough and accurately reflects your API's functionality.
Here's an example of how you might annotate your controller functions:
package controller // Get All Snippets godoc // // @Summary Get Snippets // @Description Get all snippets // @Tags Snippets // @Accept json // @Produce json // @Success 200 {object} types.APISuccessMessage // @Failure 400 {object} types.APIErrorMessage // @Failure 500 {object} types.APIErrorMessage // @Router /snippets [get] func (c *Controller) GetSnippet(ctx *gin.Context) { // Your controller function } // Create Snippet godoc // // @Summary Create a Snippet // @Description Create a Snippet // @Tags Snippets // @Accept json // @Produce json // @Security Your-Security-KeyName // @Param Snippet body types.NewSnippetRequest true "snippet" // @Success 200 {object} types.APISuccessMessage // @Failure 400 {object} types.APIErrorMessage // @Failure 500 {object} types.APIErrorMessage // @Router /snippets/create [post] func (c *Controller) CreateSnippet(ctx *gin.Context) { // Your controller function }
Note:
For this to work, you must:
- Have types for your request body and responses. For this, I created
types.APISuccessMessage
andtypes.APIErrorMessage
for my responses, andtypes.NewSnippetRequest
for a request body:
package types type APIErrorMessage struct { ErrorMessage string `json:"error"` } type APISuccessMessage struct { SuccessMessage string `json:"success"` Data any `json:"data"` } type NewSnippetRequest struct { Title string `json:"title"` Description string `json:"description"` Code string `json:"code"` }
- Use
// @Security Your-Security-KeyName
if your endpoint requires some authorization (like a JWT Token).
Your-Security-KeyName
should be the same in your controller function, and your main.go
file.
What's next?
Initialize swag again with
swag init
or
swag init -g cmd/main.go
and access the documentation at http://HOST_URL/swagger/index.html/
.
Replace HOST_URL
with your API URL.