{"id":"60145811-ec60-4f1b-a76e-3b2b2754bd27","shortId":"8ZT7uj","kind":"skill","title":"golang-swagger","tagline":"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 (","description":"**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.\n\n**Modes:**\n\n- **Build** — adding Swagger to a new or existing Go project: set up the toolchain, annotate handlers, generate docs, wire the UI endpoint.\n- **Audit** — reviewing existing swagger annotations for completeness, correctness, and security coverage.\n\n## Setup\n\nThree steps to get Swagger UI running:\n\n```bash\nswag init                        # generates docs/ with docs.go, swagger.json, swagger.yaml\nswag init -g cmd/api/main.go     # if general info is not in main.go\nswag fmt                         # format annotation comments (like go fmt)\n```\n\nImport 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:\n\n```go\nimport _ \"yourmodule/docs\"          // blank: registers spec, no identifier\nimport docs \"yourmodule/docs\"       // named: use when overriding SwaggerInfo\n```\n\nWire the UI endpoint — pick your framework:\n\n```go\n// Gin\nr.GET(\"/swagger/*any\", ginSwagger.WrapHandler(swaggerFiles.Handler))\n\n// Echo\ne.GET(\"/swagger/*\", echoSwagger.WrapHandler)\n\n// Fiber\napp.Get(\"/swagger/*\", fiberSwagger.WrapHandler(swaggerFiles.Handler))\n\n// net/http\nmux.Handle(\"/swagger/\", httpSwagger.Handler(swaggerFiles.Handler))\n\n// Chi\nr.Get(\"/swagger/*\", httpSwagger.Handler(swaggerFiles.Handler))\n```\n\nAccess the UI at `/swagger/index.html`.\n\nFor dynamic host/basepath (multi-environment), use a named import and override before serving:\n\n```go\nimport docs \"yourmodule/docs\"\n\ndocs.SwaggerInfo.Host     = os.Getenv(\"API_HOST\")\ndocs.SwaggerInfo.BasePath = \"/api/v1\"\n```\n\n[Full CLI reference](references/swag-cli.md)\n\n## General API Info\n\nPlace in `main.go` (or the file passed via `-g`). These annotations define the top-level spec:\n\n```go\n// @title           My API\n// @version         1.0\n// @description     Short description of the API.\n// @host            localhost:8080\n// @BasePath        /api/v1\n// @schemes         http https\n\n// @contact.name    API Support\n// @contact.email   support@example.com\n// @license.name    Apache 2.0\n\n// @securityDefinitions.apikey Bearer\n// @in header\n// @name Authorization\n// @description Type \"Bearer\" followed by a space and the JWT token.\n```\n\n## Operation Annotations\n\nAnnotate each handler function. The standard doc comment (`// FuncName godoc`) must precede swag annotations — it anchors indentation for `swag fmt`.\n\n```go\n// ShowAccount godoc\n// @Summary      Get account by ID\n// @Description  Returns account details for the given ID.\n// @Tags         accounts\n// @Accept       json\n// @Produce      json\n// @Param        id      path  int  true  \"Account ID\"\n// @Param        filter  query string false \"Optional search filter\"\n// @Success      200  {object}  model.Account\n// @Success      204  \"No content\"\n// @Failure      400  {object}  api.ErrorResponse\n// @Failure      404  {object}  api.ErrorResponse\n// @Router       /accounts/{id} [get]\n// @Security     Bearer\nfunc ShowAccount(c *gin.Context) {}\n```\n\n**@Param** format: `@Param <name> <in> <type> <required> \"<description>\" [attributes]`\n\n| `<in>`     | Usage                                |\n| ---------- | ------------------------------------ |\n| `path`     | URL path segment (`/users/{id}`)     |\n| `query`    | URL query string (`?filter=x`)       |\n| `body`     | Request body — type must be a struct |\n| `header`   | HTTP header                          |\n| `formData` | Multipart/form field                 |\n\nOptional attributes on `@Param`: `default(v)`, `minimum(n)`, `maximum(n)`, `minLength(n)`, `maxLength(n)`, `Enums(a,b,c)`, `example(v)`, `collectionFormat(multi)`.\n\n**@Success/@Failure** format: `@Success <code> {<kind>} <type> \"<description>\"`\n\n| `<kind>`             | When             |\n| -------------------- | ---------------- |\n| `{object}`           | Single struct    |\n| `{array}`            | Slice of structs |\n| `string` / `integer` | Primitive        |\n\n**Generics** (swag v2): `@Success 200 {object} api.Response[model.User]`\n\n**Nested composition**: `@Success 200 {object} api.Response{data=model.User}`\n\n## Security Definitions\n\nDefine once at the API level (in main.go), apply per endpoint with `@Security`.\n\n```go\n// Bearer / JWT\n// @securityDefinitions.apikey Bearer\n// @in header\n// @name Authorization\n\n// API key in header\n// @securityDefinitions.apikey ApiKeyAuth\n// @in header\n// @name X-API-Key\n\n// Basic auth\n// @securityDefinitions.basic BasicAuth\n\n// OAuth2 authorization code\n// @securityDefinitions.oauth2.authorizationCode OAuth2\n// @authorizationUrl https://example.com/oauth/authorize\n// @tokenUrl https://example.com/oauth/token\n// @scope.read Read access\n// @scope.write Write access\n```\n\nApply to an endpoint:\n\n```go\n// @Security Bearer\n// @Security OAuth2[read, write]\n// @Security BasicAuth && ApiKeyAuth   // AND — both required\n```\n\n## Struct Tags\n\nEnrich models without changing their Go type:\n\n```go\ntype CreateUserRequest struct {\n    Name   string `json:\"name\" example:\"Jane Doe\" minLength:\"2\" maxLength:\"100\"`\n    Role   string `json:\"role\" enums:\"admin,user,guest\" example:\"user\"`\n    Age    int    `json:\"age\" minimum:\"18\" maximum:\"120\"`\n    Avatar []byte `json:\"avatar\" swaggertype:\"string\" format:\"base64\"`\n    Secret string `json:\"-\" swaggerignore:\"true\"`  // excluded from docs\n}\n```\n\n| Tag | Purpose |\n| --- | --- |\n| `example` | Example value shown in Swagger UI |\n| `enums` | Comma-separated allowed values |\n| `swaggertype` | Override detected type (e.g., `\"primitive,integer\"` for `time.Time`) |\n| `swaggerignore:\"true\"` | Exclude field from the generated schema |\n| `extensions` | Add OpenAPI extensions: `extensions:\"x-nullable,x-deprecated=true\"` |\n\n## Common Mistakes\n\n| Mistake | Why it breaks | Fix |\n| --- | --- | --- |\n| Missing `_ \"yourmodule/docs\"` import | Schema not registered; UI loads empty | Add blank import in main.go or server init |\n| Stale `docs/` after code changes | Docs diverge from implementation; consumers get wrong schema | Re-run `swag init` after every annotation change |\n| `@Param body` with primitive type | swag cannot derive schema from `string`; generation fails | Always use a named struct for body params |\n| No `@Security` on protected routes | Swagger UI shows no lock icon; testers send unauthenticated requests | Apply `@Security` to every authenticated endpoint |\n| General info annotations in the wrong file | swag silently skips them; spec has no title/host | Use `-g <file>` flag or move annotations to `main.go` |\n| Using `{object}` with a map type | swag cannot generate a schema for `map[string]any` without help | Use a named struct or annotate with `swaggertype` |\n| Multi-word `@Tags` without quotes | Tags split on spaces, producing malformed grouping | Quote tags with spaces: `@Tags \"user accounts\"` |\n\n## Cross-References\n\n- → See `samber/cc-skills-golang@golang-security` for securing the Swagger UI endpoint in production (disable or gate with auth middleware).\n- → See `samber/cc-skills-golang@golang-grpc` for gRPC — use grpc-gateway with its own OpenAPI generator instead of swag.\n\nThis 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.\n\nIf you encounter a bug or unexpected behavior in swag, open an issue at <https://github.com/swaggo/swag/issues>.","tags":["golang","swagger","skills","samber","agent","agent-skills","antigravity","claude","claude-code","code","codex","coding"],"capabilities":["skill","source-samber","skill-golang-swagger","topic-agent","topic-agent-skills","topic-antigravity","topic-claude","topic-claude-code","topic-code","topic-codex","topic-coding","topic-copilot","topic-cursor","topic-gemini","topic-gemini-cli-extension"],"categories":["cc-skills-golang"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/samber/cc-skills-golang/golang-swagger","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add samber/cc-skills-golang","source_repo":"https://github.com/samber/cc-skills-golang","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 1725 github stars · SKILL.md body (7,548 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T18:53:03.301Z","embedding":null,"createdAt":"2026-05-01T06:52:49.336Z","updatedAt":"2026-05-18T18:53:03.301Z","lastSeenAt":"2026-05-18T18:53:03.301Z","tsv":"'/accounts':391 '/api/v1':245,286 '/oauth/authorize':533 '/oauth/token':537 '/swagger':194,200,204,209,214 '/swagger/index.html':221 '/swaggo/swag/issues':906 '/users':409 '1.0':275 '100':584 '120':602 '18':600 '2':582 '2.0':297 '200':375,472,479 '204':379 '400':383 '404':387 '8080':284 'accept':355 'access':217,540,543 'account':342,347,354,364,818 'accur':50 'ad':70 'add':652,679 'admin':590 'age':595,598 'allow':632 'also':161 'alway':722 'anchor':332 'annot':9,52,83,95,133,263,316,317,330,707,753,771,796 'apach':296 'api':31,41,66,242,251,273,281,291,490,508,519,878 'api.errorresponse':385,389 'api.response':474,481 'apikeyauth':513,557 'app.get':203 'appli':494,544,745 'array':461 'attribut':403,432 'audit':91 'auth':522,839 'authent':749 'author':303,507,526 'authorizationurl':530 'avatar':603,606 'b':447 'base64':610 'basepath':285 'bash':110 'basic':521 'basicauth':524,556 'bearer':299,306,395,500,503,550 'bearer/jwt':29 'behavior':897 'blank':148,171,680 'bodi':417,419,710,728 'break':668 'bug':55,894 'build':69 'byte':604 'c':398,448 'cannot':715,781 'chang':566,691,708 'chi':25,212 'cli':247 'cmd/api/main.go':122 'code':18,527,690,871 'collectionformat':451 'comma':630 'comma-separ':629 'comment':10,134,324 'common':663 'complet':51,97 'composit':477 'consum':67,696 'contact.email':293 'contact.name':290 'content':381 'context7':883 'contract':49 'correct':98 'coverag':101 'createuserrequest':572 'cross':820 'cross-refer':819 'data':482 'date':877 'default':435 'defin':264,486 'definit':28,485 'deprec':661 'deriv':716 'descript':276,278,304,345 'detail':348 'detect':636 'disabl':835 'discover':888 'diverg':693 'doc':46,86,114,140,177,238,323,618,688,692 'docs.go':116 'docs.swaggerinfo':165 'docs.swaggerinfo.basepath':244 'docs.swaggerinfo.host':240 'document':6,42,869 'doe':580 'dynam':223 'e.g':638 'e.get':199 'echo':23,198 'echoswagger.wraphandler':201 'empti':678 'encount':892 'endpoint':90,187,496,547,750,832 'engin':43 'enrich':563 'enum':445,589,628 'environ':227 'everi':706,748 'exampl':449,578,593,621,622,872 'example.com':532,536 'example.com/oauth/authorize':531 'example.com/oauth/token':535 'exclud':616,645 'exhaust':864 'exist':76,93 'extens':651,654,655 'fail':721 'failur':382,386,454 'fals':370 'fiber':24,202 'fiberswagger.wraphandler':205 'field':430,646 'file':258,757 'filter':367,373,415 'fix':669 'flag':768 'fmt':131,137,336 'follow':307 'format':132,401,455,609 'formdata':428 'framework':20,190 'full':246 'func':396 'funcnam':325 'function':320 'g':121,261,767 'gate':837 'gateway':851 'general':124,250,751 'generat':19,85,113,649,720,782,856 'generic':468 'get':106,341,393,697 'gin':22,192 'gin.context':399 'ginswagger.wraphandler':196 'github.com':905 'github.com/swaggo/swag/issues':904 'given':351 'go':40,77,136,168,191,236,270,337,499,548,568,570 'godoc':326,339 'golang':2,4,825,844 'golang-grpc':843 'golang-secur':824 'golang-swagg':1 'group':811 'grpc':845,847,850 'grpc-gateway':849 'guest':592 'handler':84,319 'header':301,425,427,505,511,515 'help':790,885 'host':243,282 'host/basepath':224 'http':288,426 'https':289 'httpswagger.handler':210,215 'icon':740 'id':344,352,360,365,392,410 'identifi':175 'implement':695 'import':138,149,158,169,176,231,237,672,681 'indent':333 'info':125,252,752 'init':17,112,120,686,704 'instead':857 'int':362,596 'integ':466,640 'integr':21,54 'issu':902 'jane':579 'json':356,358,576,587,597,605,613 'jwt':313,501 'key':32,509,520 'level':268,491 'license.name':295 'like':135 'load':677 'localhost':283 'lock':739 'main.go':129,255,493,683,773 'make':57 'malform':810 'map':778,786 'maximum':439,601 'maxlength':443,583 'middlewar':840 'minimum':437,599 'minlength':441,581 'miss':670 'mistak':664,665 'mode':68 'model':564 'model.account':377 'model.user':475,483 'move':770 'multi':226,452,800 'multi-environ':225 'multi-word':799 'multipart/form':429 'must':327,421 'mux.handle':208 'n':438,440,442,444 'name':157,179,230,302,506,516,574,577,725,793 'need':162 'nest':476 'net/http':26,207 'new':74 'nullabl':658 'oauth2':30,525,529,552 'object':376,384,388,458,473,480,775 'open':900 'openapi':653,855 'openapi/swagger':5 'oper':315 'option':371,431 'os.getenv':241 'overrid':164,182,233,635 'packag':141 'param':12,359,366,400,402,434,709,729 'pass':259 'path':361,405,407 'pattern':882 'per':495 'persona':36 'pick':188 'place':253 'platform':889 'preced':328 'prevent':53 'primit':467,639,712 'produc':357,809 'product':834 'project':78 'protect':733 'purpos':620 'queri':368,411,413 'quot':804,812 'r.get':193,213 're':701 're-run':700 'read':539,553 'refer':248,821,865 'references/swag-cli.md':249 'regist':143,172,675 'request':418,744 'requir':560 'return':346 'review':92 'role':585,588 'rout':734 'router':14,390 'run':109,702 'runtim':167 'samber/cc-skills-golang':823,842 'schema':650,673,699,717,784 'scheme':287 'scope.read':538 'scope.write':541 'search':372 'secret':611 'secur':15,27,100,394,484,498,549,551,555,731,746,826,828 'securitydefinitions.apikey':298,502,512 'securitydefinitions.basic':523 'securitydefinitions.oauth2.authorizationcode':528 'see':822,841 'segment':408 'send':742 'separ':631 'serv':235 'server':685 'set':79 'setup':102 'short':277 'show':737 'showaccount':338,397 'shown':624 'signatur':879 'silent':759 'singl':459 'skill':861 'skill-golang-swagger' 'skip':760 'slice':462 'sourc':62 'source-samber' 'space':310,808,815 'spec':145,173,269,762 'split':806 'stale':687 'standard':322 'step':104 'string':369,414,465,575,586,608,612,719,787 'struct':34,424,460,464,561,573,726,794 'success':13,374,378,453,456,471,478 'summari':11,340 'support':292 'support@example.com':294 'swag':16,111,119,130,329,335,469,703,714,758,780,859,899 'swagger':3,59,71,94,107,626,735,830 'swagger.json':117 'swagger.yaml':118 'swaggerfiles.handler':197,206,211,216 'swaggerignor':614,643 'swaggerinfo':183 'swaggertyp':607,634,798 'swaggo/swag':8,868 'tag':35,353,562,619,802,805,813,816 'tester':741 'three':103 'time.time':642 'titl':271 'title/host':765 'token':314 'tokenurl':534 'toolchain':82 'top':267 'top-level':266 'topic-agent' 'topic-agent-skills' 'topic-antigravity' 'topic-claude' 'topic-claude-code' 'topic-code' 'topic-codex' 'topic-coding' 'topic-copilot' 'topic-cursor' 'topic-gemini' 'topic-gemini-cli-extension' 'treat':45 'true':363,615,644,662 'truth':64 'type':305,420,569,571,637,713,779 'ui':60,89,108,154,186,219,627,676,736,831 'unauthent':743 'unexpect':896 'up-to-d':874 'url':406,412 'usag':404,881 'use':146,155,180,228,723,766,774,791,848 'user':591,594,817 'v':436,450 'v2':470 'valu':623,633 'version':274 'via':260 'wire':87,152,184 'without':565,789,803 'word':801 'write':542,554 'wrong':698,756 'x':416,518,657,660 'x-api-key':517 'x-deprec':659 'x-nullabl':656 'yourmodule/docs':170,178,239,671","prices":[{"id":"d8b4e608-7162-45f0-a9bd-aee176be5991","listingId":"60145811-ec60-4f1b-a76e-3b2b2754bd27","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"samber","category":"cc-skills-golang","install_from":"skills.sh"},"createdAt":"2026-05-01T06:52:49.336Z"}],"sources":[{"listingId":"60145811-ec60-4f1b-a76e-3b2b2754bd27","source":"github","sourceId":"samber/cc-skills-golang/golang-swagger","sourceUrl":"https://github.com/samber/cc-skills-golang/tree/main/skills/golang-swagger","isPrimary":false,"firstSeenAt":"2026-05-01T06:52:49.336Z","lastSeenAt":"2026-05-18T18:53:03.301Z"},{"listingId":"60145811-ec60-4f1b-a76e-3b2b2754bd27","source":"skills_sh","sourceId":"samber/cc-skills-golang/golang-swagger","sourceUrl":"https://skills.sh/samber/cc-skills-golang/golang-swagger","isPrimary":true,"firstSeenAt":"2026-05-07T20:41:58.183Z","lastSeenAt":"2026-05-07T22:41:18.950Z"}],"details":{"listingId":"60145811-ec60-4f1b-a76e-3b2b2754bd27","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"samber","slug":"golang-swagger","github":{"repo":"samber/cc-skills-golang","stars":1725,"topics":["agent","agent-skills","ai","antigravity","claude","claude-code","code","codex","coding","copilot","cursor","gemini","gemini-cli-extension","openclaw","opencode","plugin","skills","skillsmp","vibe-coding"],"license":"mit","html_url":"https://github.com/samber/cc-skills-golang","pushed_at":"2026-05-18T17:36:00Z","description":"🧑‍🎨 A collection of Golang agentic skills that works","skill_md_sha":"c11ae8f91b6ccea69e33d9ca2ae4822e695d4bb3","skill_md_path":"skills/golang-swagger/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/samber/cc-skills-golang/tree/main/skills/golang-swagger"},"layout":"multi","source":"github","category":"cc-skills-golang","frontmatter":{"name":"golang-swagger","license":"MIT","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.","compatibility":"Designed for Claude Code or similar AI coding agents. Requires go and swag CLI."},"skills_sh_url":"https://skills.sh/samber/cc-skills-golang/golang-swagger"},"updatedAt":"2026-05-18T18:53:03.301Z"}}