Resource DSL (Go)
Define resources in typed Go, generate db/crud code into the main app.
Source: the github.com/brick-org/brick/dsl module — dsl/schema/ (define.go, validate.go), dsl/ (runner.go, emit.go), dsl/cmd/dsl.
Two-app model
myapp/
go.work # use ./dsl ./app (one brick version both sides)
dsl/main.go # schema.Define(...) + dsl.Run(...)
app/
main.go # brick.New with generated resources
gen/ # brick_db.go + brick_crud.go (generated, COMMITTED)The DSL app holds the toolchain (dsl, codegen); the main app imports
only brick, brick/db, brick/schema plus its gen/ package — the
production binary never contains the DSL. See examples/shop/ in the repo.
Defining resources
def := schema.Define("deal", "deals", schema.Fields{
"title": schema.String().Required().Searchable(),
"status": schema.Enum("open", "won", "lost").Default("open").Filterable(),
"value": schema.Int().Default(0),
},
schema.WithTitle("title"),
schema.WithPK(schema.HashPK("name", 10)),
schema.WithParent(schema.NewParent("lead", schema.Cascade)),
schema.WithSingleton(schema.ScopedSingleton("team", "teams")),
schema.WithOperations(schema.DisableOps("delete")),
schema.WithLookup("slug"),
)Field constructors: String, Text, Int, Float, Bool, Timestamp,
UUID, JSON, Enum(...), ForeignKey(model), Children(resource) —
plus chainable modifiers (Required, Unique, Searchable, Filterable,
Sortable, Readonly, Hidden, Index, Email, MaxLen, Default,
OnDelete, From, Computed, Normalize, OrderBy).
PK constructors bake in the column type, so invalid combinations are
unrepresentable: UUIDPK, SeriesPK(col, template), FieldPK(col, source),
FormatPK(col, template), HashPK(col, length), PromptPK,
AutoincPK. Operations: DisableOps(...) or OnlyOps(...) (the
allow-list form).
Resource options cover every resource-level key: WithTenant, WithTitle,
WithUnique / WithIndex, WithSoftDelete, WithAudit,
WithVersioned, WithWritableOnUpdate, WithPolyFKs,
WithAutoCreate. WithSingleton disables create/list/delete automatically.
Running codegen
// dsl/main.go
if err := dsl.Run(Resources(), dsl.RunOptions{
OutDir: "../app/gen", Package: "gen", Aggregates: true,
}); err != nil { /* fail fast: names the resource */ }Run validates every def (ResourceDef.Validate — cross-references, PK args, tab* gating), then writes
gen/brick_db.go (GenerateDB) and gen/brick_crud.go
(GenerateCRUD). Output is gofmt-clean, deterministic, overwritten in
place — commit it and wire it up:
brick.Resource("deal", "deals", gen.DealSchema{Fields: gen.DealSchemaFields})Scaffolding (dsl CLI)
New project? go run ./dsl/cmd/dsl init ./dsl writes a starter DSL app
(Resources() + dsl.Run wiring). From there: go run . --out ../app/gen.
Migrating from YAML
The *.resource.yaml frontend is removed. If you're on a release that
still has it, run that release's dsl convert --dir ./resources --out ./dsl/resources.go once — it emits equivalent schema.Define
code (PK/parent columns fold into WithPK/WithParent; field chains
match generated SchemaFields). Verify the output, then upgrade and
delete the YAML directory.