Skip to content

Schema Evolution

This is where kiln differs from one-time scaffolding tools. Your schema changes over time - kiln keeps your API in sync.

The Workflow

1. Change your schema (add column, rename field, add table)
2. Migrate the database (goose, atlas, golang-migrate, raw SQL)
3. Run: kiln generate
4. Done. API matches the new schema.

What Happens on Regenerate

Auto-generated files are updated to match the new schema. Each file has an embedded checksum. If you've edited one, kiln protects your changes:

  ⚠ SKIPPED  generated/store/users.go (user-modified; use --force to overwrite)
  ✓ generated/models/users.go
  ✓ generated/handlers/users.go
  ✓ generated/router.go
  ✓ docs/openapi.yaml

Write-once files (mappers, helpers, main.go) are never touched. You update those manually when needed.

Tools for Safe Evolution

Command Use when
kiln diff Preview what would change before writing
kiln generate Regenerate, skip edited files
kiln generate --force Overwrite everything, including edits
kiln generate --table users Regenerate only one table

Why This Matters

Without kiln, a schema change means manually updating structs, handlers, validation, filters, OpenAPI spec - hoping nothing falls out of sync. With kiln, the schema is the single source of truth. Change it, regenerate, and the API is correct by construction.

Common Scenarios

Added a new column

kiln generate updates models, store, handlers, and OpenAPI automatically. If you've customized a mapper, add the new field manually.

Added a new table

kiln generate creates all new files. The router is updated. cmd/server/main.go is write-once so you'll need to add the new store and handler wiring manually.

Renamed a column

kiln generate updates the generated files. Your mapper needs manual update. If you've edited store or handler files, use kiln diff to see what changed, then apply manually or use --force.

Deleted a table

kiln generate won't delete old files - it only generates for tables that exist. Remove the old generated files manually.

Changed a column type

kiln generate updates the Go types, store queries, and validation tags. If you've edited handlers or mappers that reference the column, check them manually.

Added a CHECK constraint (enum)

kiln auto-detects the new constraint and adds oneof= validation. No config needed.

Added deleted_at column

kiln auto-detects the soft delete column and switches from hard delete to SET deleted_at = now(). No config needed.