Swagger / OpenAPI¶
The Tomoda API is documented inline on the handler functions with swaggo/swag annotations and exposed as an interactive OpenAPI 2.0 spec via Swagger UI.
Generating the spec¶
The spec is regenerated from the source code by swag:
task gen:docs
# expands to: cd backend && swag init -g cmd/server/main.go
Output files (all written to backend/docs/):
| File | Purpose |
|---|---|
docs.go |
Go file that embeds the spec via //go:embed so the binary serves it |
swagger.json |
Raw OpenAPI 2.0 JSON |
swagger.yaml |
Same content, YAML format |
These files are gitignored
backend/docs/docs.go, backend/docs/swagger.json, and backend/docs/swagger.yaml are in the root .gitignore. They are build artefacts: regenerate locally and let CI regenerate on deploy. Don't commit them.
task dev runs gen:docs automatically as part of the boot sequence, so a fresh checkout produces an up-to-date spec without any manual step.
Where it's served¶
When the server is running locally:
http://localhost:8080/swagger/index.html
The route is registered only when cfg.Server.Env != "production", so the UI is exposed in local, dev, and staging but not in prod.
The OpenAPI base metadata is set by annotations on cmd/server/main.go:
// @title Tomoda API
// @version 0.0.8
// @host localhost:8080
// @BasePath /api/v1
//
// @securityDefinitions.apikey ApiKeyAuth
// @in header
// @name X-API-Key
//
// @securityDefinitions.apikey BearerAuth
// @in header
// @name Authorization
Annotating a handler¶
Every handler funcdoc should include the swag annotations. Minimum viable set:
// CreateEvent godoc
// @Summary Create an event
// @Description Creates a new event owned by the authenticated user.
// @Tags Events
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param body body dto.CreateEventRequest true "Event payload"
// @Success 201 {object} dto.EventResponse
// @Failure 400 {object} utils.ErrorResponse
// @Failure 401 {object} utils.ErrorResponse
// @Router /events [post]
func (h *EventHandler) CreateEvent(c *gin.Context) { /* ... */ }
Conventions for new handlers:
@Tagsgroups endpoints in the UI — use the domain (Events, Friends, Chat, Auth, Discovery, Moments, Payments, Admin).@Securitymust be present on any route that requires auth (BearerAuthorApiKeyAuth). Public routes omit it.@Routeris the path without the/api/v1base —@BasePathadds it.- Reuse DTO types from
backend/internal/dto/instead of inline struct literals.
When to regenerate¶
Run task gen:docs after:
- Adding a new handler
- Changing a request or response DTO
- Editing any
@Summary,@Param,@Success, or@Failureannotation - Changing the top-level metadata in
cmd/server/main.go
CI does not currently fail on a stale spec, but the on-disk artefact is rebuilt at every deploy.
Limitations¶
- Swagger 2.0, not OpenAPI 3.x.
swaggo/swagwill support 3.x eventually; for now we live with 2.0 features. - Inline structs in handler signatures aren't picked up reliably — always declare DTOs as named types.
- File uploads need explicit
@Param file formData file true "...".
For per-domain endpoint catalogues, see the Services section.