Courses/Auto-Generated API Docs
Standalone Course~30 min12 challenges

Auto-Generated API Docs: Scalar & Swagger in Grit

Every API needs documentation. Other developers (and your future self) need to know what endpoints exist, what parameters they accept, and what they return. In this course, you will learn how Grit auto-generates interactive API documentation using gin-docs — no annotations required. You'll explore the Scalar UI, test endpoints live, and export the OpenAPI spec.


What is API Documentation?

Imagine you inherit a project with 50 API endpoints. No documentation. No comments. You have to read every handler, every route, every model to figure out what the API does. That's a nightmare — and it's surprisingly common. API documentation solves this by providing a clear, browsable reference of every endpoint your API offers.

API Documentation: A structured reference that describes every endpoint in your API: the URL, HTTP method, request parameters, request body schema, response format, authentication requirements, and example responses. Good documentation lets a developer use your API without reading a single line of source code.
OpenAPI Specification: A standard format (formerly called Swagger Specification) for describing REST APIs. It's a JSON or YAML file that machines can read and tools can use to generate documentation UIs, client SDKs, and test suites. The current version is OpenAPI 3.1.
Swagger: The original name for the OpenAPI Specification, and also a set of tools built around it. When people say "Swagger," they usually mean the interactive documentation UI that lets you browse endpoints and send test requests. Swagger was donated to the OpenAPI Initiative in 2015, but the name stuck.
Scalar: A modern, beautiful alternative to Swagger UI for displaying OpenAPI documentation. It offers a cleaner design, better search, syntax-highlighted request/response examples, and a built-in request builder. Grit uses Scalar as its documentation frontend.

Why does documentation matter? Three reasons:

  • For other developers: Frontend developers, mobile developers, and third-party integrators need to know your API's contract without reading Go code
  • For your future self: You will forget what endpoints exist, what parameters are required, and what the response looks like. Documentation is your memory
  • For testing: Interactive docs let you test endpoints directly in the browser — no Postman, no curl, no frontend needed
1

Challenge: Reflect on Undocumented APIs

Have you ever used an API without documentation? How was the experience? Think about how you figured out what endpoints existed, what parameters to send, and what the response looked like. Write down 3 problems you encountered (or would encounter) when using an undocumented API.

How gin-docs Works

Most API documentation tools require you to write annotations — special comments above every handler function describing the endpoint. That's tedious and error-prone because the annotations can drift out of sync with the actual code. Grit takes a different approach.

Grit uses gin-docs to auto-generate OpenAPI 3.1 specifications. No annotations needed. It works by introspecting your Gin routes and GORM models at startup.

Introspection: The ability of a program to examine its own structure at runtime. gin-docs reads your route registrations (which URL maps to which handler) and your model definitions (which fields exist, what types they are) to build the API specification automatically. When you add a new route or model field, the documentation updates itself.

Here's what gin-docs does when your API starts:

  1. 1.Scans your Gin router. It reads every registered route — the HTTP method, the URL path, the middleware chain, and the handler function.
  2. 2.Reads your GORM models. It inspects the struct fields, their types, JSON tags, and GORM tags to generate request/response schemas.
  3. 3.Generates the OpenAPI 3.1 spec. A complete JSON specification describing every endpoint, parameter, request body, and response schema.
  4. 4.Serves the Scalar UI. The interactive documentation is available at /docs in your browser.
What You Get — Zero Configuration
# Start your Grit API
cd apps/api && go run cmd/server/main.go

# Open your browser
http://localhost:8080/docs

# That's it. No annotations. No swagger comments.
# No yaml files to maintain. Just your routes and models.
Every time you generate a new resource with grit generate resource, the documentation updates automatically on the next server restart. The new endpoints, request schemas, and response schemas all appear in /docs without any additional work.
2

Challenge: Explore Your API Docs

Open http://localhost:8080/docs in your browser. How many endpoint groups do you see? List the group names (e.g., Auth, Users, etc.). How many total endpoints are documented?

The Scalar UI

When you open /docs, you see the Scalar UI — a modern, interactive documentation interface. Let's walk through its key features.

The left sidebar shows all your endpoint groups, organized by route prefix. Click a group to expand it and see individual endpoints. Each endpoint shows:

  • HTTP method badge — color-coded: green for GET, blue for POST, orange for PUT, red for DELETE
  • URL path — the full endpoint path including path parameters like /api/users/:id
  • Description — auto-generated from the handler name and route
  • Request builder — fill in parameters and body, then click Send to test the endpoint live
  • Response preview — shows the actual response with syntax highlighting
  • Authentication indicator — shows whether the endpoint requires a JWT token
The Scalar UI is not just documentation — it's a fully functional API client. You can send real requests to your running API, see real responses, and debug issues without leaving your browser. Think of it as Postman built into your docs.
3

Challenge: Test an Endpoint Live

Find the POST /api/auth/login endpoint in the Scalar UI. Fill in the email and password fields in the request builder. Click "Send." Does it return a token? What other fields are in the response?

Request & Response Schemas

One of gin-docs' most powerful features is automatic schema generation. It reads your GORM models and generates JSON schemas that describe the shape of request bodies and response payloads.

For example, consider a simple User model:

apps/api/internal/models/user.go
type User struct {
    ID        uint           `gorm:"primaryKey" json:"id"`
    Name      string         `gorm:"size:255;not null" json:"name" binding:"required"`
    Email     string         `gorm:"uniqueIndex;not null" json:"email" binding:"required,email"`
    Password  string         `gorm:"not null" json:"-"`
    Role      string         `gorm:"default:USER" json:"role"`
    CreatedAt time.Time      `json:"created_at"`
    UpdatedAt time.Time      `json:"updated_at"`
    DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}

From this model, gin-docs automatically generates:

  • A request schema for POST/PUT — includes name, email, role (excludes id, password, timestamps)
  • A response schema for GET — includes id, name, email, role, timestamps (excludes password)
  • Required field markers — from the binding:"required" tag
  • Type information — string, integer, boolean, datetime for each field

Fields with json:"-" (like Password and DeletedAt) are excluded from the documentation entirely. This is important — your docs never expose sensitive fields.

The binding tag does double duty. It validates incoming requests AND tells gin-docs which fields are required. binding:"required" means the field shows as required in the docs, and the API returns a 422 error if it's missing.
4

Challenge: Watch Schemas Appear

Generate a new resource with several fields:

Terminal
grit generate resource Product --fields "name:string,price:float,description:text:optional,sku:string,in_stock:bool"

Restart your API and refresh /docs. Does the Product schema appear? Can you see which fields are marked as required vs optional?

Authentication in Docs

Many endpoints require authentication — they expect a JWT token in the request headers. When you try to call a protected endpoint without a token, you get a 401 Unauthorized error. The Scalar UI lets you set your authentication token so you can test protected endpoints directly.

Here's the workflow:

  1. 1.Login via the docs. Find POST /api/auth/login, enter your email and password, click Send. Copy the access_token from the response.
  2. 2.Set the token. Look for the "Authentication" or "Auth" section in Scalar. Select "Bearer Token" and paste your access token.
  3. 3.Test protected endpoints. Now every request you send from the docs will include the Authorization: Bearer <token> header automatically.
Access tokens expire after 15 minutes. If you start getting 401 errors, you need to log in again and update the token. In a real app, the frontend handles this automatically using refresh tokens. In the docs, you do it manually.
5

Challenge: Authenticate and Test

Login via /docs using POST /api/auth/login. Copy the access token from the response. Set it in the Scalar authentication section. Then call GET /api/users. Do you get a list of users? What happens if you remove the token and try again?

Testing Endpoints

The Scalar UI is a complete API testing tool. Let's walk through testing all five CRUD operations for a resource.

POST — Create a Resource

Find the POST endpoint for your resource (e.g., POST /api/products). The request builder shows the JSON body schema with all required fields. Fill in the values and click Send. A successful creation returns a 201 Created status with the new resource in the response body.

Example: Create a Product
POST /api/products
Content-Type: application/json
Authorization: Bearer <your-token>

{
  "name": "Wireless Keyboard",
  "price": 79.99,
  "description": "Bluetooth mechanical keyboard",
  "sku": "KB-001",
  "in_stock": true
}

// Response: 201 Created
{
  "data": {
    "id": 1,
    "name": "Wireless Keyboard",
    "price": 79.99,
    "description": "Bluetooth mechanical keyboard",
    "sku": "KB-001",
    "in_stock": true,
    "created_at": "2026-03-27T10:00:00Z",
    "updated_at": "2026-03-27T10:00:00Z"
  },
  "message": "Product created successfully"
}

GET — List Resources

The list endpoint supports pagination. Use query parameters ?page=1&page_size=10 to control which page of results you see. The response includes a meta object with total count, current page, and total pages.

GET — Single Resource

Use the ID from a previous creation. For example, GET /api/products/1 returns just that one product. If the ID does not exist, you get a 404 Not Found error.

PUT — Update a Resource

Send only the fields you want to change. For example, to update just the price, send {"price": 69.99} to PUT /api/products/1. Other fields remain unchanged.

DELETE — Remove a Resource

Send DELETE /api/products/1. The resource is soft-deleted (the DeletedAt timestamp is set). It disappears from list queries but remains in the database for recovery if needed.

6

Challenge: Full CRUD Through Docs

Using only the Scalar UI at /docs (no frontend, no curl, no Postman), perform the complete CRUD cycle:

  1. Create a new resource
  2. List all resources to verify it appears
  3. Get the single resource by ID
  4. Update one field
  5. Get it again to verify the update
  6. Delete it
  7. Try to get it again — what status code do you receive?

Response Format

Grit enforces a consistent JSON response format across all endpoints. This predictability makes frontend development much easier — you always know the shape of the response.

Success — Single Item

Response Format
{
  "data": {
    "id": 1,
    "name": "Wireless Keyboard",
    "price": 79.99
  },
  "message": "Product created successfully"
}

Success — List with Pagination

Response Format
{
  "data": [
    { "id": 1, "name": "Keyboard" },
    { "id": 2, "name": "Mouse" }
  ],
  "meta": {
    "total": 47,
    "page": 1,
    "page_size": 20,
    "pages": 3
  }
}

Error Response

Response Format
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Name is required",
    "details": {
      "name": "This field is required",
      "price": "Must be greater than 0"
    }
  }
}

The three shapes are always the same:

  • Single item: data (object) + message (string)
  • List: data (array) + meta (pagination object)
  • Error: error.code (string) + error.message (string) + optional error.details (object)
7

Challenge: Trigger Each Response Format

Trigger all three response formats and observe the structure:

  1. Call POST /api/auth/register with valid data — observe the "data + message" format
  2. Call GET /api/users?page=1&page_size=5 — observe the "data + meta" format
  3. Call POST /api/auth/register with an empty body — observe the "error" format. What error code and message do you see?

Exporting the Spec

The OpenAPI specification is not just for the Scalar UI — it's a portable, machine-readable file that many tools can consume. You can export it and import it into:

  • Postman — import as a collection with all endpoints pre-configured
  • Insomnia — another popular API client that reads OpenAPI specs
  • API client generators — tools like openapi-generator can create TypeScript, Python, or Java clients from your spec
  • API testing tools — tools like Dredd or Schemathesis can validate your API against the spec

The raw OpenAPI JSON is available at:

OpenAPI Spec URL
# Raw JSON specification
http://localhost:8080/docs/openapi.json

# Copy this URL or download the file
# Import into Postman: File → Import → URL → paste the URL
When sharing your API with other teams, you can send them just the OpenAPI spec file. They can import it into their tool of choice and have a complete, interactive reference of your API — even if they do not have access to your running server.
8

Challenge: Export and Import

Open http://localhost:8080/docs/openapi.json in your browser. You should see the raw JSON specification. Try importing it into Postman: File → Import → paste the URL. Does Postman create a collection with all your endpoints?

Customization

gin-docs provides several configuration options to customize the generated documentation.

Authentication Configuration

By default, gin-docs detects your JWT middleware and adds Bearer Token authentication to the spec. You can customize the auth configuration:

gin-docs Auth Config
// gin-docs reads your middleware to determine which
// endpoints require authentication.
//
// Protected routes (behind AuthMiddleware) are marked
// with a lock icon in the Scalar UI.
//
// Public routes (like /api/auth/login) show no lock.

Route Grouping

Endpoints are grouped by their route prefix. For example, all /api/users/* endpoints appear under the "Users" group. All /api/auth/* endpoints appear under "Auth." This grouping happens automatically based on your Gin route groups.

Excluding Endpoints

Some internal endpoints (like health checks or metrics) should not appear in public documentation. gin-docs excludes internal routes that are not part of your API groups. The /docs endpoint itself is also excluded — documentation does not document itself.

9

Challenge: Explore the Configuration

Look at how gin-docs is configured in your project. Find the setup code in your routes file or main.go. What options are being passed? Can you identify where route groups are defined and how they map to the documentation sections?

Summary

Let's review everything you've learned:

ConceptKey Point
gin-docsAuto-generates OpenAPI 3.1 specs by introspecting routes and models
Scalar UIInteractive docs + API client at /docs
SchemasGenerated from GORM models, respects json:"-" and binding tags
AuthenticationSet Bearer token in Scalar to test protected endpoints
Response FormatConsistent: data+message, data+meta, or error object
ExportDownload OpenAPI JSON, import into Postman/Insomnia
10

Challenge: Three Resources, Docs Only

Generate three related resources:

Terminal
grit generate resource Category --fields "name:string,description:text:optional"
grit generate resource Product --fields "name:string,price:float,sku:string,category_id:belongs_to"
grit generate resource Order --fields "product_id:belongs_to,quantity:int,total:float,status:string"

Restart your API and open /docs. Using ONLY the Scalar UI (no frontend, no curl, no code), complete these tasks:

  1. Create 5 categories
  2. Create 10 products, each linked to a category
  3. Create 3 orders for different products
  4. List all products filtered by category
  5. Update an order status
11

Challenge: Export Your Spec

After creating all three resources, download the OpenAPI spec from /docs/openapi.json. How many endpoints does it contain? How many schemas? Try importing it into Postman or Insomnia.

12

Challenge: Teach Someone Else

Explain to a teammate (or write down in your own words) how Grit's API documentation works. Cover: (1) how gin-docs generates the spec, (2) how to test endpoints in Scalar, (3) how to authenticate in the docs, and (4) how to export the spec. If you can explain it clearly, you understand it.