Use when adding or maintaining OpenAPI/Swagger documentation for a Go
Scanned 9/6/2026
Install to Claude Code
npx -y skills add muratmirgun/gophers --skill go-swagger --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Go Swagger?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/muratmirgun-go-swagger-gophers)More formats (shields.io, HTML) on the badges page.
---
name: go-swagger
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.
user-invocable: false
license: MIT
compatibility: 'Designed for Claude Code or similar AI coding agents. Requires Go
1.21+, swaggo/swag v1.16+ (CLI: `swag`).'
allowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*)
metadata:
openclaw:
emoji: 📋
homepage: https://github.com/muratmirgun/gophers
requires:
bins:
- go
install:
- kind: go
package: github.com/swaggo/swag/cmd/swag@latest
bins:
- swag
---
# Go Swagger / OpenAPI with swaggo
`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.
## Core Rules
1. **Docs are a contract.** A field documented as required is the API's promise; a mismatch with the implementation is a bug.
2. **Annotations live next to handlers.** Not in a separate `docs/` folder — comments rot when separated from code.
3. **Regenerate on every change.** `swag init` is part of the build (`go generate` or a Makefile target). Stale `docs/` is worse than no docs.
4. **The `docs` package must be imported.** A blank import (`_ "yourmod/docs"`) registers the spec at process start.
5. **Use named structs for request/response bodies.** swag cannot derive a schema from `map[string]any` or a primitive type.
6. **Security definitions match implementation.** If the API enforces JWT, declare `@securityDefinitions.apikey Bearer` and annotate every protected endpoint with `@Security Bearer`.
## Install and Bootstrap
```bash
go install github.com/swaggo/swag/cmd/swag@latest
swag init # general info from main.go
swag init -g cmd/api/main.go # custom main path
swag fmt # format annotation comments like gofmt
```
Wire the UI for your framework — choose one:
```go
// Gin
import (
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
)
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
// Echo
r.GET("/swagger/*", echoSwagger.WrapHandler)
// Fiber
app.Get("/swagger/*", fiberSwagger.WrapHandler(swaggerFiles.Handler))
// Chi / net/http
mux.Handle("/swagger/", httpSwagger.Handler(swaggerFiles.Handler))
```
Import the generated spec:
```go
import _ "github.com/acme/myapi/docs" // blank: just register
import docs "github.com/acme/myapi/docs" // named: override host at runtime
```
> Read [references/swag-cli.md](../../../skills/go-swagger/references/swag-cli.md) for the CLI flag inventory and Makefile patterns.
## General API Info
Place in the file passed via `-g` (usually `main.go`):
```go
// @title Orders API
// @version 1.0
// @description Orders, customers, shipments.
// @contact.name API Support
// @contact.email api@acme.example
// @license.name Apache-2.0
// @host api.acme.example
// @BasePath /api/v1
// @schemes https http
// @securityDefinitions.apikey Bearer
// @in header
// @name Authorization
// @description Use "Bearer <token>"
```
For multi-environment deployments, set host/basepath at runtime instead of hard-coding:
```go
import docs "github.com/acme/myapi/docs"
func main() {
docs.SwaggerInfo.Host = os.Getenv("API_HOST")
docs.SwaggerInfo.BasePath = "/api/v1"
// ...
}
```
## Operation Annotations
```go
// GetOrder godoc
// @Summary Get an order by ID
// @Tags orders
// @Produce json
// @Param id path string true "Order ID (UUID)"
// @Success 200 {object} api.OrderResponse
// @Failure 404 {object} api.ErrorResponse
// @Router /orders/{id} [get]
// @Security Bearer
func GetOrder(c *gin.Context) { /* ... */ }
```
**`@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)`.
**`@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}`.
> Read [references/annotations.md](../../../skills/go-swagger/references/annotations.md) for the full annotation grammar, edge cases, and security definitions.
## Security
Declare schemes once globally (`@securityDefinitions.apikey Bearer`, `@securityDefinitions.oauth2.authorizationCode`, `@securityDefinitions.basic`) and apply per endpoint:
```go
// @Security Bearer
// @Security OAuth2[read, write]
// @Security BasicAuth && Bearer // both required (AND)
```
Endpoints without `@Security` are documented as public — match the implementation.
## Struct Tags
Enrich 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"`.
```go
type CreateOrderRequest struct {
Status string `json:"status" enums:"pending,paid,shipped"`
Total int64 `json:"total" minimum:"0" example:"19999"`
PlacedAt time.Time `json:"placed_at" swaggertype:"string" format:"date-time"`
Internal string `json:"-" swaggerignore:"true"`
}
```
> Read [references/struct-tags.md](../../../skills/go-swagger/references/struct-tags.md) for type overrides (`time.Time`, `uuid.UUID`, `decimal.Decimal`, custom scalars) and NULL handling.
## Make Target
```makefile
.PHONY: docs
docs:
swag fmt
swag init -g cmd/api/main.go --parseDependency --parseInternal
check-docs: docs
@git diff --quiet docs || (echo "docs/ is stale; run make docs"; exit 1)
```
Run `make check-docs` in CI to catch annotation drift before merge.
## Anti-Patterns
| Anti-pattern | Why it hurts | Do this instead |
|---|---|---|
| Forgetting `_ "yourmod/docs"` | UI loads empty, no errors | Add the blank import in main |
| `@Param body string` | swag cannot derive a schema from a primitive | Use a named struct |
| Stale `docs/` after handler change | Docs lie to clients | Regenerate in CI; fail on drift |
| General info in wrong file | Spec has no title/host | Use `-g <file>` or move to main |
| `{object} map[string]any` | swag silently empty | Define a wrapper struct |
| No `@Security` on protected route | UI shows no lock icon | Add `@Security` everywhere auth is required |
| Multi-word `@Tags` unquoted | Tags split on whitespace | Quote: `@Tags "order management"` |
| Exposing `/swagger/*` in production unconditionally | Public API surface map | Gate behind env flag or auth |
## Verification Checklist
- [ ] `swag init` runs clean (no warnings)
- [ ] `docs/` is committed and up-to-date with handlers
- [ ] Every handler has `@Summary`, `@Router`, and at least one `@Success`
- [ ] Every protected handler has `@Security`
- [ ] Request bodies are named structs (no `map`, no primitives)
- [ ] Generic / nested response wrappers are spelled correctly (`Response[T]` or `Response{data=T}`)
- [ ] `/swagger/*` is gated in production (env flag or auth middleware)
- [ ] CI fails when `docs/` drifts from annotations
## References
- [references/swag-cli.md](../../../skills/go-swagger/references/swag-cli.md) — CLI flags, parsing options, Makefile patterns
- [references/annotations.md](../../../skills/go-swagger/references/annotations.md) — full annotation grammar with examples
- [references/struct-tags.md](../../../skills/go-swagger/references/struct-tags.md) — type overrides, time/UUID/decimal handling
- [references/anti-patterns.md](../../../skills/go-swagger/references/anti-patterns.md) — detailed walkthrough of each failure mode
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!