What is a resource?

Model + handler + service + types + routes — the standard slice.

5 mineasy

Before we run the generator, you need to know what it generates. Spoiler: it's a resource. This 5-minute lesson defines the word.

A resource is a complete vertical slice

For each domain concept (User, Order, Invoice, Product), Grit produces a slice that spans the whole stack:

Model GORM struct apps/api/internal/models/order.go
Service Business logic apps/api/internal/services/order.go
Handler HTTP layer apps/api/internal/handlers/order.go
Route Wiring apps/api/internal/routes/routes.go (injected)
Zod schema Validation packages/shared/src/schemas/order.ts
TS type Frontend type packages/shared/src/types/order.ts
React Query hook Data fetching apps/web/hooks/use-orders.ts
Admin resource Filament-style page apps/admin/app/resources/orders/

That's eight artefacts for one concept — too many to write by hand every time you add an entity. The generator writes all of them in one command.

The mental model

A resource exists to do CRUD on a thing:

  • Create — POST /api/orders
  • Read one — GET /api/orders/:id
  • Read many — GET /api/orders (with pagination)
  • Update — PUT /api/orders/:id
  • Delete — DELETE /api/orders/:id

Five endpoints, one model, one admin page. The handler, service, type, schema, hook, and admin page all line up to make that flow work end-to-end.

Not every domain concept needs to be a resource. Notification is a service (you don't CRUD notifications — you send them). Order is a resource (you create, list, update, cancel them). If you'd expose all 5 verbs to a UI, it's a resource.

Fields define the shape

When you generate a resource, you tell the generator what fields the model has:

Terminal
$grit generate resource Order \
$ --field "customerId:uuid:required" \
$ --field "total:decimal:required" \
$ --field "status:string:default=pending"

Each field becomes: a GORM column, a Zod validator, a TS type property, an admin form input, a DataTable column. The generator knows the mapping for every supported type.

Quick check

Which of these is most likely NOT a Grit resource?

Try it

In your notes.md, list 5 concepts from a real product you know (your job's app, a side project, anything). For each, write "resource" or "not a resource" and one sentence why.

What's next

You know what a resource is. Time to make one — next lesson we run grit generate resource Product end-to-end.

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