Generating a Product resource
The command, the prompts, what each flag controls.
Let's generate a Product resource. By the end of this lesson you will have eight new files on disk, wired into routes, with a working admin page.
The command
$grit generate resource Product \$ --field "name:string:required" \$ --field "price:decimal:required" \$ --field "description:text" \$ --field "stockQuantity:int:default=0"
Run that from the project root. You'll see:
ā Wrote apps/api/internal/models/product.goā Wrote apps/api/internal/services/product.goā Wrote apps/api/internal/handlers/product.goā Injected routes into apps/api/internal/routes/routes.goā Wrote packages/shared/src/schemas/product.tsā Wrote packages/shared/src/types/product.tsā Wrote apps/web/hooks/use-products.tsā Wrote apps/admin/app/resources/products/page.tsxNext steps:grit migrate # adds the products tablegrit start # restart dev servers to pick up the new code
Field types
The generator understands a small but solid set:
| Field type | Go | TypeScript | Admin input |
|---|---|---|---|
| string | string | string | text input |
| text | string | string | textarea |
| int | int | number | number input |
| decimal | decimal.Decimal | string | money input |
| bool | bool | boolean | switch |
| date | time.Time | string | date picker |
| uuid | uuid.UUID | string | FK select |
| json | datatypes.JSON | unknown | JSON editor |
Field modifiers
requiredā NOT NULL + Zod.required()uniqueā DB unique index + Zod refinedefault=valueā column default + Zod defaultbelongs_to=Customerā foreign key + relation
grit generate resource Product without flags. It prompts you for fields one at a time ā useful when you're not sure what to call them yet.What happened to the database?
Nothing yet. The generator writes the Go struct (the GORM model) but doesn't create the table. Run grit migrate after every generate ā it AutoMigrate's the new model, creating the table + columns + indexes.
Quick check
Try it
Generate the Product resource on your machine:
$grit generate resource Product \$ --field "name:string:required" \$ --field "price:decimal:required" \$ --field "stockQuantity:int:default=0"$grit migrate# restart dev servers if they don't hot reload
Then hit GET /api/products and paste the response (the empty paginated list) in notes.md.
What's next
Eight files showed up. Next lesson is the tour ā open every one, understand what each does, see how they connect.
Spot a typo? Have an idea?
Help us improve this lesson. One click opens a GitHub issue with the lesson URL pre-filled ā suggest clearer wording, report a bug, or request more depth. The course keeps improving thanks to learners like you.
Suggest an improvement on GitHub