| name | go-swagger3-docs |
| description | Documents existing Go HTTP APIs with go-swagger3 godoc @ annotations and struct tags, then generates OpenAPI 3 specs. Use when the user asks to document an API, add Swagger/OpenAPI comments, generate oas.json/yml, or mentions go-swagger3. |
go-swagger3 — document existing Go APIs
Copy this file into a consumer project as .claude/skills/go-swagger3-docs/SKILL.md.
Annotate existing Go code with go-swagger3 godoc @ tags and struct tags, then run the CLI. Prefer editing comments and tags over rewriting handlers.
Install
go install github.com/parvez3019/go-swagger3@latest
export PATH="$HOME/go/bin:$PATH"
docker run -t --rm -v $(pwd):/app -w /app parvez3019/go-swagger3:latest \
--module-path . --main-file-path ./cmd/api/main.go --output oas.json --schema-without-pkg
Workflow
- Confirm
go.mod exists (Go modules only).
- Put service annotations on the main/entry file (
@Title and @Version required).
- Annotate each HTTP handler’s godoc (comments must sit directly above the func).
- Add
json + OAS tags on request/response structs; add @Enum / @HeaderParameters types when needed.
- Generate (pick the matching layout):
go-swagger3 --module-path . --output oas.json --schema-without-pkg
go-swagger3 --module-path . --main-file-path ./cmd/api/main.go --output oas.json --schema-without-pkg
go-swagger3 --module-path . --main-file-path ./cmd/api/main.go --handler-path ./internal/handlers --output oas.json --schema-without-pkg
go-swagger3 --module-path . --main-file-path ./cmd/api/main.go --output oas.json --schema-without-pkg --generate-yaml
- Open the output, fix gaps, re-run with
--debug if needed. Use --strict when hardening.
CLI flags
| Flag | Purpose |
|---|
--module-path | Module root to scan |
--main-file-path | File with service-level annotations |
--handler-path | Optional: only scan handlers under this path |
--output | Output path (default oas.json) |
--schema-without-pkg | Schema names without package prefix |
--generate-yaml | Emit YAML (.json output becomes .yml) |
--exclude | Comma-separated dirs to skip |
--quiet | Reduce log noise |
--debug | Debug logging |
--strict | Treat parse warnings as fatal |
Also: go-swagger3 fmt -d ./ formats @ annotations.
Framework UI
Serve UI via github.com/parvez3019/go-swagger3/swagger (net/http) or adapters under swagger/gin, swagger/echo, swagger/chi, swagger/mux, swagger/fiber, swagger/hertz, swagger/buffalo, swagger/flamingo, swagger/atreugo. See docs/MIGRATION_FROM_SWAG.md and examples/.
Extra operation annotations
@Accept / @Produce (MIME aliases: json, xml, mpfd, …)
- Per-handler
@Security, @deprecated, @externalDocs.description / .url
@Param attributes: Enums(), default(), minimum(), Format(), style(), explode(), …
- Generics:
PaginatedResult[User]; composition: JSONResult{data=Order}
Patterns
Service (main file)
package main
func main() {}
Shared headers
type Headers struct {
Authorization string `json:"Authorization" example:"Bearer <token>" skip:"true"`
Version string `json:"Client-Version" description:"Client Version"`
Language string `json:"Client-Language" $ref:"LanguageEnum"`
Platform string `json:"Client-Platform" example:"android" description:"Available values : android, ios, web"`
}
type LanguageEnum struct {
LanguageEnum string `enum:"en-in,en-id,id,en-mx,es-mx" example:"en-in"`
}
Handler operations
Prefer @Router and {object} / {array}. Both @Route/@Router and object/{object} work. Case-insensitive. @Tag aliases @Resource.
@Param shape: @Param {name} {in} {goType} {required} "{desc}" ["{example}"]
in: path, query, form, header, cookie, body, file
required: true, false, required, optional
Descriptions and examples must be quoted.
POST body
func CreateUser() {}
GET with query + nested filter
func GetRestaurants() {}
Path params + array response
func GetGroupUsers() {}
PUT / PATCH / DELETE
func UpdateUser() {}
func DeleteUser() {}
File upload, cookie, header param
func UploadAvatar() {}
func GetSession() {}
Status-only / string response / response headers
func Live() {}
func CreateUpdate() {}
func Login() {}
Models, enums, field tags
type OrderByEnum struct {
OrderByEnum string `enum:"nearest,popular,new,highest-rated" example:"popular"`
}
type CreateUserRequest struct {
FirstName string `json:"first_name" readOnly:"true"`
LastName string `json:"last_name" example:"Hassan" description:"Last name"`
Age int `json:"age" minimum:"18" exclusiveMinimum:"true" maximum:"256" exclusiveMaximum:"true"`
EmailID string `json:"email_id" pattern:"[\\w.]+@[\\w.]"`
UserName string `json:"user_name" title:"login"`
Password string `json:"password" minLength:"6" maxLength:"200"`
Roles []string `json:"roles" writeOnly:"true" nullable:"true" uniqueItems:"true" minItems:"1" maxItems:"100"`
Country string `json:"country" $ref:"CountriesEnum"`
Version string `json:"version" override-example:"11.0.0"`
}
type CreateUserResponse struct {
UserID string `json:"user_id" example:"u_123"`
}
type GetRestaurantsResponse struct {
Restaurants []Restaurant `json:"restaurants" maxProperties:"100" minProperties:"2" additionalProperties:"true"`
}
type ErrorResponse struct {
Code string `json:"code"`
Msg string `json:"msg" skip:"true"`
Secret string `json:"-"`
}
type CountriesEnum struct {
CountriesEnum string `enum:"india,china,mexico,japan" example:"india"`
}
Useful tags: example, description, title, required, nullable, readOnly, writeOnly, minimum, maximum, exclusiveMinimum, exclusiveMaximum, minLength, maxLength, pattern, minItems, maxItems, uniqueItems, minProperties, maxProperties, additionalProperties, enum, $ref, override-example, skip:"true". Hide with json:"-" or go-swagger3:"-".
Security (global only)
Also: oauth2Implicit, oauth2ResourceOwnerCredentials, oauth2ClientCredentials. Security applies to the entire service — not per operation.
End-to-end example (minimal API)
func main() {}
func ListItems() {}
type Item struct {
ID string `json:"id" example:"1"`
Name string `json:"name" example:"Widget"`
}
type ErrorResponse struct {
Message string `json:"message"`
}
Troubleshooting (for agents)
Work top-down. After each fix, re-run the CLI.
| Symptom | Likely cause | What to do |
|---|
command not found: go-swagger3 | Binary not on PATH | export PATH="$HOME/go/bin:$PATH" or use Docker |
Empty / missing info.title or info.version | Service comments not on --main-file-path | Move @Title/@Version to the main file; pass --main-file-path explicitly |
| No paths in output | Handlers lack @Router/@Route, or --handler-path excludes them | Add @Router /path [method]; widen or drop --handler-path |
| Handler present but operation missing | Comments not on the func godoc, or package outside module | Put // @... directly above func; keep handlers inside the module |
| Schema / type missing or wrong | Wrong package-qualified name, or type not imported/reachable | Use pkg.Type as in Go; ensure the type is in-module or a scanned dependency |
Schema names look like handler.User | Package prefix included | Pass --schema-without-pkg |
operation ID 'X' is not unique | Duplicate @OperationId | Make each @OperationId unique across the module |
Parse warnings / --strict fails | Malformed @Param/@Success (missing quotes, bad in, bad status) | Match examples; quote descriptions; valid in values only |
| Field missing from schema | skip:"true", json:"-", or go-swagger3:"-" | Remove skip/hide tags if the field should appear |
| Nested / anonymous field wrong | Anonymous embedded structs unsupported | Give the field an explicit named type |
| Security missing on one route | Per-operation security not supported | Define @Security / @SecurityScheme on the service file only |
Unknown tags ignored (e.g. @Accept) | Not a go-swagger3 annotation | Use only supported tags listed above |
| YAML not produced | Forgot flag or wrong extension expectation | Pass --generate-yaml (tool rewrites .json → .yml) |
| Still stuck | Need parser detail | Re-run with --debug and fix the first real error |
Rules
- Do not invent unsupported annotations (
@Accept, swag-only tags, etc.).
- Do not claim per-operation security.
- Anonymous struct fields are not supported.
- Go modules only.
- Prefer godoc/tag edits over handler rewrites unless asked.
- Keep
@OperationId values unique.