For generate API documentation, By Using swag (from swaggo) to generate Swagger/OpenAPI documentation in your Go projects. you can follow my step below
Install swag CLI tool (Only first time / Update Version)
- Install swag CLI tool with this command
 
go install github.com/swaggo/swag/cmd/swag@latest
- Test generates a sample document. Run this command in the root directory of your Go project, where your main.go
 
swag init
- if your main.go not located and root directory but located in [ROOT_PATH]/cmd/api/main.go you can use -g option to specify main.go location
 
swag init -g "cmd/api/main.go"
- result is an empty swagger doc
 
Add swag tag/annotation to your Go code
There are 2 locations
- main.go Example
 
// @title Calc EOD API // @version 1.0 // @description This is the API documentation for the Calc EOD project. // @termsOfService http://swagger.io/terms/ // @contact.name API Support // @contact.url http://www.example.com/support // @contact.email [email protected] // @license.name MIT // @license.url https://opensource.org/licenses/MIT // @host localhost:3000 // @BasePath / // @securityDefinitions.apiKey ApiKeyAuth // @in header // @name Authorization // @schemes http func main() { ... your logic }
- your handler function Example
 
// Login handles user login requests.
// @Summary      Login user
// @Description  Authenticate user and return JWT token
// @Tags         auth
// @Accept       json
// @Produce      json
// @Param        request  body      entities.LoginRequest  true  "Login Request"
// @Success      200      {object}  entities.LoginResponse
// @Failure      400      {object}  map[string]string
// @Failure      401      {object}  map[string]string
// @Router       /auth/login [post]
func (h *AuthHandler) Login(c *fiber.Ctx) error {
	var request entities.LoginRequest
	if err := c.BodyParser(&request); err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
			"error": "Invalid request body",
		})
	}
	if err := utils.ValidateStruct(&request); err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
			"error":   "Validation failed",
			"details": err.Error(),
		})
	}
	response, err := h.authService.Login(&request)
	if err != nil {
		return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
			"error": "Invalid email or password",
		})
	}
	return c.Status(fiber.StatusOK).JSON(response)
}
// RefreshToken handles token refresh requests.
// @Summary      Refresh JWT token
// @Description  Refresh an expired JWT token
// @Tags         auth
// @Accept       json
// @Produce      json
// @Param        Authorization  header    string  true  "JWT Token"
// @Success      200           {object}  map[string]string
// @Failure      401           {object}  map[string]string
// @Router       /auth/refresh-token [post]
func (h *AuthHandler) RefreshToken(c *fiber.Ctx) error {
	token := c.Get("Authorization")
	if token == "" {
		return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
			"error": "Missing authorization token",
		})
	}
	newToken, err := h.authService.RefreshToken(token)
	if err != nil {
		return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
			"error": "Invalid or expired token",
		})
	}
	return c.Status(fiber.StatusOK).JSON(fiber.Map{
		"token": newToken,
	})
}
Note: you can use AI to help generate swag tag/annotation to your Go code. My prompt "I want you to add Swagger annotations to handler functions and select file auth_handler.go" in my Git Copilot Console
Update Doc Again
- run init command
 
swag init #or main.go not located and root directory such as cmd/api/main.go swag init -g "cmd/api/main.go"
Add Swagger UI to your project
Install the middleware for your web framework (for example, gin):
- gin
 
go get -u github.com/swaggo/gin-swagger go get -u github.com/swaggo/files
import (
    "github.com/gin-gonic/gin"
    "github.com/swaggo/gin-swagger"
    "github.com/swaggo/files"
    _ "your/project/docs" // docs is generated by Swag CLI, you have to import it.
)
func main() {
    r := gin.Default()
    // ...
    r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
    r.Run()
}- fiber
 
go get github.com/gofiber/swagger
import (
    "github.com/gofiber/fiber/v2"
    "github.com/gofiber/swagger"
    _ "your/module/docs" // replace with your module path
)
func main() {
    app := fiber.New()
    
    // Swagger route
    app.Get("/swagger/*", swagger.HandlerDefault) // default route
    // Your other routes...
    app.Listen(":8080")
}- echo
 
go get github.com/swaggo/echo-swagger
import (
    "github.com/labstack/echo/v4"
    echoSwagger "github.com/swaggo/echo-swagger"
    _ "your/module/docs" // replace with your module path
)
func main() {
    e := echo.New()
    // Swagger route
    e.GET("/swagger/*", echoSwagger.WrapHandler)
    // Your other routes...
    e.Logger.Fatal(e.Start(":8080"))
}And access your swagger doc via [YOUR_BASE_PATH]/swagger/index.html, the image below is Go fiber example

Reference
Discover more from naiwaen@DebuggingSoft
Subscribe to get the latest posts sent to your email.



