PluginBench
Skill
Pass
Audit score 90

golang-swagger

samber/cc-skills-golang

Generate OpenAPI/Swagger documentation for Go APIs using swaggo/swag annotations and framework integrations.

What is golang-swagger?

Golang-swagger automates OpenAPI/Swagger spec generation from annotated Go handler functions. Use it when building or maintaining API documentation in Go projects, especially those using gin, echo, fiber, chi, or net/http frameworks.

  • Annotate handlers with @Summary, @Param, @Success, @Failure, @Router, and @Security comments
  • Generate OpenAPI specs (docs.go, swagger.json, swagger.yaml) via `swag init`
  • Wire Swagger UI endpoints to gin, echo, fiber, chi, or net/http routers
  • Define security schemes (Bearer/JWT, OAuth2, API key, Basic auth) at the API level
  • Enrich struct fields with example values, enums, min/max constraints, and type overrides via struct tags
  • Exclude sensitive fields from docs using swaggerignore tags

How to install golang-swagger

npx skills add https://github.com/samber/cc-skills-golang --skill golang-swagger
Prerequisites
  • Go installed and configured
  • swag CLI: `go install github.com/swaggo/swag/cmd/swag@latest`
  • One of: github.com/swaggo/gin-swagger, github.com/swaggo/echo-swagger, github.com/swaggo/http-swagger, or github.com/swaggo/files (depending on your framework)
Claude Code
Cursor
Windsurf
Cline

How to use golang-swagger

  1. 1.Run `swag init` (or `swag init -g cmd/api/main.go` if general info is in a non-main file) to generate docs/ with docs.go, swagger.json, and swagger.yaml
  2. 2.Add a blank or named import of the generated docs package in your main.go or server initialization file
  3. 3.Wire the Swagger UI endpoint using your framework's handler (e.g., `r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))` for gin)
  4. 4.Access the UI at `/swagger/index.html` to verify the spec is loaded
  5. 5.For dynamic host/basePath, use a named import and override `docs.SwaggerInfo.Host` and `docs.SwaggerInfo.BasePath` before serving

Use cases

Good for
  • Add Swagger UI to an existing Go API to auto-document all endpoints and request/response schemas
  • Audit and fix incomplete or incorrect annotations to ensure docs match implementation
  • Set up multi-environment API documentation by dynamically overriding host and basePath at runtime
  • Document complex nested response types and generic responses using swag v2 syntax
  • Enforce security coverage by marking authenticated endpoints with @Security annotations
Who it's for
  • Go backend engineers building REST APIs
  • API documentation maintainers ensuring specs stay in sync with code
  • Teams using gin, echo, fiber, chi, or net/http frameworks
  • API consumers and integration testers relying on Swagger UI as the source of truth

golang-swagger FAQ

What happens if I don't run `swag init` after changing annotations?

The generated docs/ files become stale and out of sync with your code. Swagger UI will show outdated schemas. Always re-run `swag init` after annotation changes.

Can I use a primitive type (e.g., string) for @Param body?

No. The `@Param body` directive requires a named struct so swag can derive the schema. Using a primitive type will cause generation to fail.

How do I document endpoints that require authentication?

Define a security scheme once in main.go (e.g., `@securityDefinitions.apikey Bearer`), then apply `@Security Bearer` to each protected endpoint. This adds a lock icon in Swagger UI.

Can I override the host and basePath for different environments?

Yes. Use a named import (`import docs "yourmodule/docs"`), then set `docs.SwaggerInfo.Host` and `docs.SwaggerInfo.BasePath` at runtime before serving.

How do I exclude sensitive fields from the Swagger spec?

Add the `swaggerignore:"true"` struct tag to any field you want hidden from the generated schema.

Full instructions (SKILL.md)

Source of truth, from samber/cc-skills-golang.


name: golang-swagger description: "Golang OpenAPI/Swagger documentation with swaggo/swag — annotation comments (@Summary, @Param, @Success, @Router, @Security), swag init code generation, framework integrations (gin, echo, fiber, chi, net/http), security definitions (Bearer/JWT, OAuth2, API key), and struct tags (swaggertype, enums, example, swaggerignore). Apply when adding or maintaining Swagger/OpenAPI docs in a Go project, or when the codebase imports github.com/swaggo/swag, github.com/swaggo/gin-swagger, github.com/swaggo/echo-swagger, github.com/swaggo/http-swagger, or github.com/swaggo/files." user-invocable: true license: MIT compatibility: Designed for Claude Code or similar AI coding agents. Requires go and swag CLI. metadata: author: samber version: "1.0.2" openclaw: emoji: "📋" homepage: https://github.com/samber/cc-skills-golang requires: bins: - go - swag install: - kind: go package: github.com/swaggo/swag/cmd/swag@latest bins: [swag] skill-library-version: "2.0.0-rc5" allowed-tools: Read Edit Write Glob Grep Bash(go:) Bash(golangci-lint:) Bash(git:) Agent WebFetch mcp__context7__resolve-library-id mcp__context7__query-docs Bash(swag:) AskUserQuestion

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.

Dependencies:

  • swag: go install github.com/swaggo/swag/cmd/swag@latest

Setup

Three steps to get Swagger UI running:

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:

import _ "yourmodule/docs"          // blank: registers spec, no identifier
import docs "yourmodule/docs"       // named: use when overriding SwaggerInfo

Wire the UI endpoint — pick your framework:

// 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:

import docs "yourmodule/docs"

docs.SwaggerInfo.Host     = os.Getenv("API_HOST")
docs.SwaggerInfo.BasePath = "/api/v1"

Full CLI reference

General API Info

Place in main.go (or the file passed via -g). These annotations define the top-level spec:

// @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.

// 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
pathURL path segment (/users/{id})
queryURL query string (?filter=x)
bodyRequest body — type must be a struct
headerHTTP header
formDataMultipart/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 / integerPrimitive

Generics (swag v2): @Success 200 {object} api.Response[model.User]

Nested composition: @Success 200 {object} api.Response{data=model.User}

Security Definitions

Define once at the API level (in main.go), apply per endpoint with @Security.

// 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:

// @Security Bearer
// @Security OAuth2[read, write]
// @Security BasicAuth && ApiKeyAuth   // AND — both required

Struct Tags

Enrich models without changing their Go type:

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
exampleExample value shown in Swagger UI
enumsComma-separated allowed values
swaggertypeOverride detected type (e.g., "primitive,integer" for time.Time)
swaggerignore:"true"Exclude field from the generated schema
extensionsAdd OpenAPI extensions: extensions:"x-nullable,x-deprecated=true"

Common Mistakes

MistakeWhy it breaksFix
Missing _ "yourmodule/docs" importSchema not registered; UI loads emptyAdd blank import in main.go or server init
Stale docs/ after code changesDocs diverge from implementation; consumers get wrong schemaRe-run swag init after every annotation change
@Param body with primitive typeswag cannot derive schema from string; generation failsAlways use a named struct for body params
No @Security on protected routesSwagger 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 typeswag cannot generate a schema for map[string]any without helpUse a named struct or annotate with swaggertype
Multi-word @Tags without quotesTags split on spaces, producing malformed groupingQuote tags with spaces: @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. For Go package docs, versions, symbols, and known vulnerabilities, → See samber/cc-skills-golang@golang-pkg-go-dev skill.

If you encounter a bug or unexpected behavior in swag, open an issue at https://github.com/swaggo/swag/issues.