← GophersCONTENT HISTORYWHAT CHANGED · RULE-BASED ANALYSIS
Update to Gophers
Snapshot Sep 30, 2026 · 23:14 UTC · version 0.1.0
Collection source: not recorded for this historical snapshot.
First saved snapshot
No earlier snapshot is available to establish a change.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"description": "Use when adding or maintaining OpenAPI/Swagger documentation for a Go HTTP API. Covers swaggo/swag annotation comments (@Summary, @Param, @Success, @Router, @Security), the swag CLI workflow, framework integration for Gin/Echo/Fiber/Chi/net-http, security definitions (Bearer/JWT, OAuth2, API key), and struct tags (example, enums, swaggertype, swaggerignore). Apply when a project imports github.com/swaggo/swag or any of the swaggo UI adapters, or when you need to expose /swagger/index.html.",
"included_files": [
{
"relative_path": "agents/openai.yaml",
"size_in_bytes": 234
},
{
"relative_path": "references/annotations.md",
"size_in_bytes": 4722
},
{
"relative_path": "references/anti-patterns.md",
"size_in_bytes": 4136
},
{
"relative_path": "references/struct-tags.md",
"size_in_bytes": 4716
},
{
"relative_path": "references/swag-cli.md",
"size_in_bytes": 3631
}
],
"name": "go-swagger",
"skill_md_contents": "---\nname: go-swagger\ndescription: \"Use when adding or maintaining OpenAPI/Swagger documentation for a Go HTTP API. Covers swaggo/swag annotation comments (@Summary, @Param, @Success, @Router, @Security), the swag CLI workflow, framework integration for Gin/Echo/Fiber/Chi/net-http, security definitions (Bearer/JWT, OAuth2, API key), and struct tags (example, enums, swaggertype, swaggerignore). Apply when a project imports github.com/swaggo/swag or any of the swaggo UI adapters, or when you need to expose /swagger/index.html.\"\nlicense: MIT\ncompatibility: \"Designed for Claude Code or similar AI coding agents. Requires Go 1.21+, swaggo/swag v1.16+ (CLI: `swag`).\"\nallowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*)\n---\n\n# Go Swagger / OpenAPI with swaggo\n\n`github.com/swaggo/swag` is the de-facto annotation-driven OpenAPI generator for Go. You annotate handlers with `// @...` comments, run the `swag` CLI, and get `docs/swagger.json`, `docs/swagger.yaml`, and `docs/docs.go` for the UI.\n\n## Core Rules\n\n1. **Docs are a contract.** A field documented as required is the API's promise; a mismatch with the implementation is a bug.\n2. **Annotations live next to handlers.** Not in a separate `docs/` folder — comments rot when separated from code.\n3. **Regenerate on every change.** `swag init` is part of the build (`go generate` or a Makefile target). Stale `docs/` is worse than no docs.\n4. **The `docs` package must be imported.** A blank import (`_ \"yourmod/docs\"`) registers the spec at process start.\n5. **Use named structs for request/response bodies.** swag cannot derive a schema from `map[string]any` or a primitive type.\n6. **Security definitions match implementation.** If the API enforces JWT, declare `@securityDefinitions.apikey Bearer` and annotate every protected endpoint with `@Security Bearer`.\n\n## Install and Bootstrap\n\n```bash\ngo install github.com/swaggo/swag/cmd/swag@latest\nswag init # general info from main.go\nswag init -g cmd/api/main.go # custom main path\nswag fmt # format annotation comments like gofmt\n```\n\nWire the UI for your framework — choose one:\n\n```go\n// Gin\nimport (\n swaggerFiles \"github.com/swaggo/files\"\n ginSwagger \"github.com/swaggo/gin-swagger\"\n)\nr.GET(\"/swagger/*any\", ginSwagger.WrapHandler(swaggerFiles.Handler))\n\n// Echo\nr.GET(\"/swagger/*\", echoSwagger.WrapHandler)\n\n// Fiber\napp.Get(\"/swagger/*\", fiberSwagger.WrapHandler(swaggerFiles.Handler))\n\n// Chi / net/http\nmux.Handle(\"/swagger/\", httpSwagger.Handler(swaggerFiles.Handler))\n```\n\nImport the generated spec:\n\n```go\nimport _ \"github.com/acme/myapi/docs\" // blank: just register\nimport docs \"github.com/acme/myapi/docs\" // named: override host at runtime\n```\n\n> Read [references/swag-cli.md](references/swag-cli.md) for the CLI flag inventory and Makefile patterns.\n\n## General API Info\n\nPlace in the file passed via `-g` (usually `main.go`):\n\n```go\n// @title Orders API\n// @version 1.0\n// @description Orders, customers, shipments.\n// @contact.name API Support\n// @contact.email api@acme.example\n// @license.name Apache-2.0\n// @host api.acme.example\n// @BasePath /api/v1\n// @schemes https http\n\n// @securityDefinitions.apikey Bearer\n// @in header\n// @name Authorization\n// @description Use \"Bearer <token>\"\n```\n\nFor multi-environment deployments, set host/basepath at runtime instead of hard-coding:\n\n```go\nimport docs \"github.com/acme/myapi/docs\"\n\nfunc main() {\n docs.SwaggerInfo.Host = os.Getenv(\"API_HOST\")\n docs.SwaggerInfo.BasePath = \"/api/v1\"\n // ...\n}\n```\n\n## Operation Annotations\n\n```go\n// GetOrder godoc\n// @Summary Get an order by ID\n// @Tags orders\n// @Produce json\n// @Param id path string true \"Order ID (UUID)\"\n// @Success 200 {object} api.OrderResponse\n// @Failure 404 {object} api.ErrorResponse\n// @Router /orders/{id} [get]\n// @Security Bearer\nfunc GetOrder(c *gin.Context) { /* ... */ }\n```\n\n**`@Param`:** `@Param <name> <in> <type> <required> \"<desc>\" [attributes]` — `<in>` is one of `path`, `query`, `body`, `header`, `formData`. Useful attributes: `default(v)`, `minimum(n)`, `maximum(n)`, `Enums(a,b,c)`, `example(v)`, `collectionFormat(multi)`.\n\n**`@Success` / `@Failure`:** `@<kw> <code> {<kind>} <type> \"<desc>\"` — `{object}` (struct), `{array}` (slice), or a primitive (`string`, `integer`). Generics (swag v2): `api.Response[model.Order]`. Composition: `api.Response{data=model.Order}`.\n\n> Read [references/annotations.md](references/annotations.md) for the full annotation grammar, edge cases, and security definitions.\n\n## Security\n\nDeclare schemes once globally (`@securityDefinitions.apikey Bearer`, `@securityDefinitions.oauth2.authorizationCode`, `@securityDefinitions.basic`) and apply per endpoint:\n\n```go\n// @Security Bearer\n// @Security OAuth2[read, write]\n// @Security BasicAuth && Bearer // both required (AND)\n```\n\nEndpoints without `@Security` are documented as public — match the implementation.\n\n## Struct Tags\n\nEnrich models without changing their Go type. Common tags: `example`, `enums:\"a,b,c\"`, `minimum`/`maximum`, `minLength`/`maxLength`, `format`, `swaggertype` (override detected type, e.g. `time.Time` → string), `swaggerignore:\"true\"`, and `extensions:\"x-nullable,x-deprecated=true\"`.\n\n```go\ntype CreateOrderRequest struct {\n Status string `json:\"status\" enums:\"pending,paid,shipped\"`\n Total int64 `json:\"total\" minimum:\"0\" example:\"19999\"`\n PlacedAt time.Time `json:\"placed_at\" swaggertype:\"string\" format:\"date-time\"`\n Internal string `json:\"-\" swaggerignore:\"true\"`\n}\n```\n\n> Read [references/struct-tags.md](references/struct-tags.md) for type overrides (`time.Time`, `uuid.UUID`, `decimal.Decimal`, custom scalars) and NULL handling.\n\n## Make Target\n\n```makefile\n.PHONY: docs\ndocs:\n\tswag fmt\n\tswag init -g cmd/api/main.go --parseDependency --parseInternal\n\ncheck-docs: docs\n\t@git diff --quiet docs || (echo \"docs/ is stale; run make docs\"; exit 1)\n```\n\nRun `make check-docs` in CI to catch annotation drift before merge.\n\n## Anti-Patterns\n\n| Anti-pattern | Why it hurts | Do this instead |\n|---|---|---|\n| Forgetting `_ \"yourmod/docs\"` | UI loads empty, no errors | Add the blank import in main |\n| `@Param body string` | swag cannot derive a schema from a primitive | Use a named struct |\n| Stale `docs/` after handler change | Docs lie to clients | Regenerate in CI; fail on drift |\n| General info in wrong file | Spec has no title/host | Use `-g <file>` or move to main |\n| `{object} map[string]any` | swag silently empty | Define a wrapper struct |\n| No `@Security` on protected route | UI shows no lock icon | Add `@Security` everywhere auth is required |\n| Multi-word `@Tags` unquoted | Tags split on whitespace | Quote: `@Tags \"order management\"` |\n| Exposing `/swagger/*` in production unconditionally | Public API surface map | Gate behind env flag or auth |\n\n## Verification Checklist\n\n- [ ] `swag init` runs clean (no warnings)\n- [ ] `docs/` is committed and up-to-date with handlers\n- [ ] Every handler has `@Summary`, `@Router`, and at least one `@Success`\n- [ ] Every protected handler has `@Security`\n- [ ] Request bodies are named structs (no `map`, no primitives)\n- [ ] Generic / nested response wrappers are spelled correctly (`Response[T]` or `Response{data=T}`)\n- [ ] `/swagger/*` is gated in production (env flag or auth middleware)\n- [ ] CI fails when `docs/` drifts from annotations\n\n## References\n\n- [references/swag-cli.md](references/swag-cli.md) — CLI flags, parsing options, Makefile patterns\n- [references/annotations.md](references/annotations.md) — full annotation grammar with examples\n- [references/struct-tags.md](references/struct-tags.md) — type overrides, time/UUID/decimal handling\n- [references/anti-patterns.md](references/anti-patterns.md) — detailed walkthrough of each failure mode\n"
}SHA-256 of public snapshot: e2351414bbcdfe5b2d2a8b9205dc3430cfd7fc2b1c6acf6f29d72ed36bbd12fe