What gen resource emits
npx flare gen resource Contact --fields "name:string, email:string"writes or updates:
| File | Content |
|---|---|
resources/contact.resource.ts |
The descriptor (inside a generated block) — your source of truth |
db/schema/contacts.ts |
The Drizzle table: id text PK, one column per stored field, created_at/updated_at, enum CHECK constraints, belongsTo FK + index |
db/schema.ts |
Re-exports every db/schema/* table (generated block) |
migrations/NNNN_create_contacts.sql |
From the app’s own drizzle-kit generate |
app/api/contacts/route.ts |
GET (list) and POST (create) |
app/api/contacts/[id]/route.ts |
GET, PATCH, PUT, DELETE |
resources/contact.client.ts |
contactClient and the Contact/ContactCreate/ContactUpdate types |
resources/contact.validators.ts |
contactValidators — Zod, derived from the descriptor at runtime |
resources/index.ts |
The registry of every descriptor, for the admin and seeders |
lib/api.ts |
Created once, if missing: the authorize hook every resource API calls |
db/relations.ts |
Drizzle relations() for every resource, regenerated on every gen |
app/admin/<slug>/page.tsx, new/page.tsx, [id]/edit/page.tsx |
Thin wrappers over <ResourceTable> / <ResourceFormPage> |
Route files are thin: they call createResourceHandlers() from
@flaredev/core/server, which reads the descriptor at runtime. There’s no
separate build step to keep the API and the descriptor in sync.
The REST API, briefly
Section titled “The REST API, briefly”- List —
?page,?perPage(≤100),?sort=field|-field,?q=(aLIKEsearch over searchable fields, with%/_escaped), and?filter[field]=value(nullmeansIS NULL). Sorting and filtering are only allowed on fields the descriptor permits — sortable is everything excepttext/file; filterable defaults toenum/boolean/belongsTo. Responses look like{ data, meta: { page, perPage, total, totalPages } }. - Errors —
400invalid query/JSON,401/403fromauthorize,403on a cross-origin write,404,409on a unique violation (with the offendingfield) or a delete blocked by a reference,415non-JSON body,422validation (withissues[]), a missing FK target, or a CHECK failure. - Security —
authorizeruns before anything else, always. The defaultlib/api.tsjust requires a Better Auth session; see roles & policies for per-resource rules. Every write needsContent-Type: application/jsonand a same-originOriginheader.
createResourceHandlers checks at startup that the table has a column for
every field the descriptor declares, so an edited descriptor with no
matching migration fails loudly instead of silently dropping data.
Re-running the generator
Section titled “Re-running the generator”gen resource on an existing resource is an update, not a fresh
write — see the codegen overwrite contract
for exactly what that means for hand-written code, and
sync-types for detecting drift between the
descriptor and everything derived from it.