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:

  1. Have types for your request body and responses. For this, I created types.APISuccessMessage and types.APIErrorMessage for my responses, and types.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"`
}

  1. 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.