golang-swagger

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
Persona: You are a Go API documentation engineer. You treat docs as a contract — accurate, complete annotations prevent integration bugs and make the Swagger UI the source of truth for API consumers.
Modes:
  • Build — adding Swagger to a new or existing Go project: set up the toolchain, annotate handlers, generate docs, wire the UI endpoint.
  • Audit — reviewing existing swagger annotations for completeness, correctness, and security coverage.
角色定位: 你是一名Go API文档工程师。你将文档视为契约——准确、完整的注释可以避免集成bug,并让Swagger UI成为API消费者的事实来源。
工作模式:
  • 构建模式 —— 为新的或现有Go项目添加Swagger:设置工具链、为处理器添加注释、生成文档、配置UI端点。
  • 审计模式 —— 检查现有Swagger注释的完整性、正确性和安全覆盖范围。

Setup

环境搭建

Three steps to get Swagger UI running:
bash
swag init                        # generates docs/ with docs.go, swagger.json, swagger.yaml
swag init -g cmd/api/main.go     # if general info is not in main.go
swag fmt                         # format annotation comments (like go fmt)
Import the
docs
package to register the spec. Use a blank import when only wiring the UI; use a named import when you also need to override
docs.SwaggerInfo
at runtime:
go
import _ "yourmodule/docs"          // blank: registers spec, no identifier
import docs "yourmodule/docs"       // named: use when overriding SwaggerInfo
Wire the UI endpoint — pick your framework:
go
// Gin
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))

// Echo
e.GET("/swagger/*", echoSwagger.WrapHandler)

// Fiber
app.Get("/swagger/*", fiberSwagger.WrapHandler(swaggerFiles.Handler))

// net/http
mux.Handle("/swagger/", httpSwagger.Handler(swaggerFiles.Handler))

// Chi
r.Get("/swagger/*", httpSwagger.Handler(swaggerFiles.Handler))
Access the UI at
/swagger/index.html
.
For dynamic host/basepath (multi-environment), use a named import and override before serving:
go
import docs "yourmodule/docs"

docs.SwaggerInfo.Host     = os.Getenv("API_HOST")
docs.SwaggerInfo.BasePath = "/api/v1"
Full CLI reference
三步启动Swagger UI:
bash
swag init                        # 生成docs/目录,包含docs.go、swagger.json、swagger.yaml
swag init -g cmd/api/main.go     # 如果通用信息不在main.go中
swag fmt                         # 格式化注释(类似go fmt)
导入
docs
包以注册规范。仅配置UI时使用空白导入;需要在运行时覆盖
docs.SwaggerInfo
时使用命名导入:
go
import _ "yourmodule/docs"          // 空白导入:注册规范,无标识符
import docs "yourmodule/docs"       // 命名导入:覆盖SwaggerInfo时使用
配置UI端点——选择你的框架:
go
// Gin
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))

// Echo
e.GET("/swagger/*", echoSwagger.WrapHandler)

// Fiber
app.Get("/swagger/*", fiberSwagger.WrapHandler(swaggerFiles.Handler))

// net/http
mux.Handle("/swagger/", httpSwagger.Handler(swaggerFiles.Handler))

// Chi
r.Get("/swagger/*", httpSwagger.Handler(swaggerFiles.Handler))
访问UI的地址为
/swagger/index.html
如需动态主机/基础路径(多环境),使用命名导入并在服务启动前覆盖:
go
import docs "yourmodule/docs"

docs.SwaggerInfo.Host     = os.Getenv("API_HOST")
docs.SwaggerInfo.BasePath = "/api/v1"
完整CLI参考文档

General API Info

通用API信息

Place in
main.go
(or the file passed via
-g
). These annotations define the top-level spec:
go
// @title           My API
// @version         1.0
// @description     Short description of the API.
// @host            localhost:8080
// @BasePath        /api/v1
// @schemes         http https

// @contact.name    API Support
// @contact.email   support@example.com
// @license.name    Apache 2.0

// @securityDefinitions.apikey Bearer
// @in header
// @name Authorization
// @description Type "Bearer" followed by a space and the JWT token.
将以下内容放置在
main.go
中(或通过
-g
参数指定的文件)。这些注释定义了顶层规范:
go
// @title           My API
// @version         1.0
// @description     Short description of the API.
// @host            localhost:8080
// @BasePath        /api/v1
// @schemes         http https

// @contact.name    API Support
// @contact.email   support@example.com
// @license.name    Apache 2.0

// @securityDefinitions.apikey Bearer
// @in header
// @name Authorization
// @description Type "Bearer" followed by a space and the JWT token.

Operation Annotations

操作注释

Annotate each handler function. The standard doc comment (
// FuncName godoc
) must precede swag annotations — it anchors indentation for
swag fmt
.
go
// ShowAccount godoc
// @Summary      Get account by ID
// @Description  Returns account details for the given ID.
// @Tags         accounts
// @Accept       json
// @Produce      json
// @Param        id      path  int  true  "Account ID"
// @Param        filter  query string false "Optional search filter"
// @Success      200  {object}  model.Account
// @Success      204  "No content"
// @Failure      400  {object}  api.ErrorResponse
// @Failure      404  {object}  api.ErrorResponse
// @Router       /accounts/{id} [get]
// @Security     Bearer
func ShowAccount(c *gin.Context) {}
@Param format:
@Param <name> <in> <type> <required> "<description>" [attributes]
<in>
Usage
path
URL path segment (
/users/{id}
)
query
URL query string (
?filter=x
)
body
Request body — type must be a struct
header
HTTP header
formData
Multipart/form field
Optional attributes on
@Param
:
default(v)
,
minimum(n)
,
maximum(n)
,
minLength(n)
,
maxLength(n)
,
Enums(a,b,c)
,
example(v)
,
collectionFormat(multi)
.
@Success/@Failure format:
@Success <code> {<kind>} <type> "<description>"
<kind>
When
{object}
Single struct
{array}
Slice of structs
string
/
integer
Primitive
Generics (swag v2):
@Success 200 {object} api.Response[model.User]
Nested composition:
@Success 200 {object} api.Response{data=model.User}
为每个处理器函数添加注释。标准文档注释(
// FuncName godoc
)必须位于swag注释之前——它为
swag fmt
提供缩进锚点。
go
// ShowAccount godoc
// @Summary      Get account by ID
// @Description  Returns account details for the given ID.
// @Tags         accounts
// @Accept       json
// @Produce      json
// @Param        id      path  int  true  "Account ID"
// @Param        filter  query string false "Optional search filter"
// @Success      200  {object}  model.Account
// @Success      204  "No content"
// @Failure      400  {object}  api.ErrorResponse
// @Failure      404  {object}  api.ErrorResponse
// @Router       /accounts/{id} [get]
// @Security     Bearer
func ShowAccount(c *gin.Context) {}
@Param格式:
@Param <name> <in> <type> <required> "<description>" [attributes]
<in>
用途
path
URL路径段(
/users/{id}
query
URL查询字符串(
?filter=x
body
请求体——类型必须为结构体
header
HTTP请求头
formData
多部分表单字段
@Param
的可选属性:
default(v)
minimum(n)
maximum(n)
minLength(n)
maxLength(n)
Enums(a,b,c)
example(v)
collectionFormat(multi)
@Success/@Failure格式:
@Success <code> {<kind>} <type> "<description>"
<kind>
适用场景
{object}
单个结构体
{array}
结构体切片
string
/
integer
基本类型
泛型(swag v2):
@Success 200 {object} api.Response[model.User]
嵌套组合
@Success 200 {object} api.Response{data=model.User}

Security Definitions

安全定义

Define once at the API level (in main.go), apply per endpoint with
@Security
.
go
// Bearer / JWT
// @securityDefinitions.apikey Bearer
// @in header
// @name Authorization

// API key in header
// @securityDefinitions.apikey ApiKeyAuth
// @in header
// @name X-API-Key

// Basic auth
// @securityDefinitions.basic BasicAuth

// OAuth2 authorization code
// @securityDefinitions.oauth2.authorizationCode OAuth2
// @authorizationUrl https://example.com/oauth/authorize
// @tokenUrl https://example.com/oauth/token
// @scope.read Read access
// @scope.write Write access
Apply to an endpoint:
go
// @Security Bearer
// @Security OAuth2[read, write]
// @Security BasicAuth && ApiKeyAuth   // AND — both required
在API层面定义一次(在main.go中),通过
@Security
应用到每个端点。
go
// Bearer / JWT
// @securityDefinitions.apikey Bearer
// @in header
// @name Authorization

// 请求头中的API密钥
// @securityDefinitions.apikey ApiKeyAuth
// @in header
// @name X-API-Key

// 基础认证
// @securityDefinitions.basic BasicAuth

// OAuth2授权码
// @securityDefinitions.oauth2.authorizationCode OAuth2
// @authorizationUrl https://example.com/oauth/authorize
// @tokenUrl https://example.com/oauth/token
// @scope.read 读取权限
// @scope.write 写入权限
应用到端点:
go
// @Security Bearer
// @Security OAuth2[read, write]
// @Security BasicAuth && ApiKeyAuth   // 逻辑与——两者均需满足

Struct Tags

结构体标签

Enrich models without changing their Go type:
go
type CreateUserRequest struct {
    Name   string `json:"name" example:"Jane Doe" minLength:"2" maxLength:"100"`
    Role   string `json:"role" enums:"admin,user,guest" example:"user"`
    Age    int    `json:"age" minimum:"18" maximum:"120"`
    Avatar []byte `json:"avatar" swaggertype:"string" format:"base64"`
    Secret string `json:"-" swaggerignore:"true"`  // excluded from docs
}
TagPurpose
example
Example value shown in Swagger UI
enums
Comma-separated allowed values
swaggertype
Override detected type (e.g.,
"primitive,integer"
for
time.Time
)
swaggerignore:"true"
Exclude field from the generated schema
extensions
Add OpenAPI extensions:
extensions:"x-nullable,x-deprecated=true"
无需修改Go类型即可丰富模型信息:
go
type CreateUserRequest struct {
    Name   string `json:"name" example:"Jane Doe" minLength:"2" maxLength:"100"`
    Role   string `json:"role" enums:"admin,user,guest" example:"user"`
    Age    int    `json:"age" minimum:"18" maximum:"120"`
    Avatar []byte `json:"avatar" swaggertype:"string" format:"base64"`
    Secret string `json:"-" swaggerignore:"true"`  // 从文档中排除
}
标签用途
example
在Swagger UI中显示示例值
enums
逗号分隔的允许值列表
swaggertype
覆盖自动检测的类型(例如,将
time.Time
指定为
"primitive,integer"
swaggerignore:"true"
将字段从生成的Schema中排除
extensions
添加OpenAPI扩展:
extensions:"x-nullable,x-deprecated=true"

Common Mistakes

常见错误

MistakeWhy it breaksFix
Missing
_ "yourmodule/docs"
import
Schema not registered; UI loads emptyAdd blank import in main.go or server init
Stale
docs/
after code changes
Docs diverge from implementation; consumers get wrong schemaRe-run
swag init
after every annotation change
@Param body
with primitive type
swag cannot derive schema from
string
; generation fails
Always use a named struct for body params
No
@Security
on protected routes
Swagger UI shows no lock icon; testers send unauthenticated requestsApply
@Security
to every authenticated endpoint
General info annotations in the wrong fileswag silently skips them; spec has no title/hostUse
-g <file>
flag or move annotations to
main.go
Using
{object}
with a map type
swag cannot generate a schema for
map[string]any
without help
Use a named struct or annotate with
swaggertype
Multi-word
@Tags
without quotes
Tags split on spaces, producing malformed groupingQuote tags with spaces:
@Tags "user accounts"
错误影响修复方案
缺失
_ "yourmodule/docs"
导入
Schema未注册;UI加载为空在main.go或服务器初始化代码中添加空白导入
代码变更后
docs/
目录未更新
文档与实现不一致;消费者获取错误的Schema每次修改注释后重新运行
swag init
@Param body
使用基本类型
swag无法从
string
推导Schema;生成失败
始终为请求体参数使用命名结构体
受保护路由未添加
@Security
Swagger UI未显示锁图标;测试者发送未认证请求为每个需要认证的端点添加
@Security
通用信息注释放置在错误文件中swag会静默忽略这些注释;规范中缺少标题/主机信息使用
-g <file>
参数或将注释移至
main.go
对map类型使用
{object}
swag无法为
map[string]any
生成Schema(无额外配置时)
使用命名结构体或添加
swaggertype
注释
多词
@Tags
未加引号
标签会按空格拆分,导致分组异常为带空格的标签添加引号:
@Tags "user accounts"

Cross-References

交叉参考

  • → See
    samber/cc-skills-golang@golang-security
    for securing the Swagger UI endpoint in production (disable or gate with auth middleware).
  • → See
    samber/cc-skills-golang@golang-grpc
    for gRPC — use grpc-gateway with its own OpenAPI generator instead of swag.
This skill is not exhaustive. Refer to the swaggo/swag documentation and code examples for up-to-date API signatures and usage patterns. Context7 can help as a discoverability platform.
If you encounter a bug or unexpected behavior in swag, open an issue at https://github.com/swaggo/swag/issues.
  • → 参考
    samber/cc-skills-golang@golang-security
    了解生产环境中如何保护Swagger UI端点(禁用或通过认证中间件限制访问)。
  • → 参考
    samber/cc-skills-golang@golang-grpc
    了解gRPC相关内容——请使用grpc-gateway自带的OpenAPI生成器,而非swag。
本技能内容并非详尽无遗。如需最新的API签名和使用模式,请参考swaggo/swag官方文档和代码示例。Context7可作为发现平台提供帮助。
如果在使用swag时遇到bug或异常行为,请在https://github.com/swaggo/swag/issues提交问题。