Brick

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.

On this page