# Go Swagger

> 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.co…

- **Type:** Skill
- **Install:** `agentstack add skill-muratmirgun-gophers-go-swagger`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [muratmirgun](https://agentstack.voostack.com/s/muratmirgun)
- **Installs:** 0
- **Category:** [Developer Tools](https://agentstack.voostack.com/c/developer-tools)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [muratmirgun](https://github.com/muratmirgun)
- **Source:** https://github.com/muratmirgun/gophers/tree/main/skills/go-swagger

## Install

```sh
agentstack add skill-muratmirgun-gophers-go-swagger
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# 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](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 "
```

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     "" [attributes]` — `` 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`:** `@  {}  ""` — `{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](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](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 ` 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](references/swag-cli.md) — CLI flags, parsing options, Makefile patterns
- [references/annotations.md](references/annotations.md) — full annotation grammar with examples
- [references/struct-tags.md](references/struct-tags.md) — type overrides, time/UUID/decimal handling
- [references/anti-patterns.md](references/anti-patterns.md) — detailed walkthrough of each failure mode

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [muratmirgun](https://github.com/muratmirgun)
- **Source:** [muratmirgun/gophers](https://github.com/muratmirgun/gophers)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-muratmirgun-gophers-go-swagger
- Seller: https://agentstack.voostack.com/s/muratmirgun
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
