API Documentation
Every Grit project ships with auto-generated, interactive API documentation powered by gin-docs. No annotations, no comments, no manual spec files — your docs are generated directly from your Gin routes and GORM models.
How It Works
When you scaffold a project with grit new, gin-docs is mounted in your routes file with a single function call. It introspects your Gin router and GORM models at startup to generate a complete OpenAPI 3.1 specification.
Zero annotations. gin-docs reads your route definitions, struct tags (json, binding, gorm, docs), and handler signatures to generate documentation automatically. No // @Summary comments needed.
What You Get
After running your API, these endpoints are available:
| Endpoint | Description |
|---|---|
GET /docs | Interactive Scalar UI |
GET /docs?ui=swagger | Swagger UI alternative |
GET /docs/openapi.json | OpenAPI 3.1 spec (JSON) |
GET /docs/openapi.yaml | OpenAPI 3.1 spec (YAML) |
GET /docs/export/postman | Postman Collection v2.1 |
GET /docs/export/insomnia | Insomnia export |
Configuration
The mount call in routes.go configures everything:
// API Documentation (gin-docs)gindocs.Mount(r, db, gindocs.Config{Title: cfg.AppName + " API",Description: "REST API built with Grit — Go + React meta-framework.",Version: "1.0.0",UI: gindocs.UIScalar, // or gindocs.UISwaggerScalarTheme: "kepler",Models: []interface{}{&models.User{}, &models.Upload{}, &models.Blog{}},Auth: gindocs.AuthConfig{Type: gindocs.AuthBearer,BearerFormat: "JWT",},})
Config Options
| Option | Default | Description |
|---|---|---|
Prefix | /docs | URL path for the docs UI |
Title | API Documentation | API title shown in the UI |
Version | 1.0.0 | API version |
UI | UISwagger | UIScalar or UISwagger |
ScalarTheme | kepler | Scalar UI theme (kepler, moon, purple, saturn, etc.) |
Models | [] | GORM models for schema generation |
Auth | AuthNone | AuthConfig{Type: AuthBearer, BearerFormat: "JWT"} |
DevMode | false | Regenerate spec on every request |
ReadOnly | false | Disable “Try It Out” in the UI |
ExcludeRoutes | [] | Glob patterns to exclude routes |
GORM Model Schemas
When you pass GORM models to the Models config, gin-docs automatically generates three schema variants for each model:
- Full Model — includes ID and timestamps, used for responses
- Create Variant — excludes auto-generated fields (ID, timestamps)
- Update Variant — all fields optional, for PATCH operations
This means your struct tags drive the documentation:
type User struct {ID uint `json:"id" gorm:"primarykey"`FirstName string `json:"first_name" binding:"required,min=2"`LastName string `json:"last_name" binding:"required,min=2"`Email string `json:"email" binding:"required,email" gorm:"uniqueIndex"`Password string `json:"-"`Role string `json:"role" binding:"oneof=ADMIN EDITOR USER" gorm:"default:'USER'"`Active bool `json:"active" gorm:"default:true"`CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"`UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"`}
Struct tags matter: binding:"required" marks fields as required, binding:"oneof=A B C" creates enums, json:"-" hides fields (like passwords), gorm:"primarykey" and gorm:"autoCreateTime" mark fields as read-only in create/update variants.
Customizing Route Documentation
While gin-docs infers most documentation automatically, you can customize individual routes using the fluent builder API:
docs := gindocs.Mount(r, db, gindocs.Config{...})// Override a specific route's documentationdocs.Route("POST /api/users").Summary("Create a new user").Description("Creates a user account with the given details.").RequestBody(CreateUserInput{}).Response(201, User{}, "User created successfully").Tags("Users")
Or use inline middleware for per-handler documentation:
r.POST("/api/users",gindocs.Doc(gindocs.DocConfig{Summary: "Create user",RequestBody: CreateUserInput{},Response: User{},}),userHandler.Create,)
Adding Models for New Resources
When you generate a new resource with grit generate resource, add the model to the Models slice in the gin-docs config:
gindocs.Mount(r, db, gindocs.Config{// ...Models: []interface{}{&models.User{},&models.Upload{},&models.Blog{},&models.Product{}, // ← add new models here&models.Category{},},})
Excluding Routes
You can hide internal or admin-only routes from the documentation:
gindocs.Mount(r, db, gindocs.Config{// ...ExcludeRoutes: []string{"/api/admin/*"},ExcludePrefixes: []string{"/studio", "/sentinel"},})
Switching Between UIs
Grit defaults to the Scalar UI (modern, dark theme), but you can switch to Swagger UI in config:
// Use Swagger UI insteadgindocs.Config{UI: gindocs.UISwagger,}
You can also switch at runtime by adding a query parameter: /docs?ui=swagger or /docs?ui=scalar.
Exporting Specs
Use the export endpoints to import your API into other tools:
GET /docs/openapi.json— for any OpenAPI-compatible toolGET /docs/openapi.yaml— YAML formatGET /docs/export/postman— import directly into PostmanGET /docs/export/insomnia— import directly into Insomnia