Resources and Operations
As your API grows, the most important organization decision is simple: group related operations into resources.
- a resource is a group such as
todo,account, orauth - an operation is one contract such as
GetTodoorCreateTodo
Typeweaver generates code from that structure, so a clean resource map keeps the output easy to navigate.
This page is about grouping and naming the surface of your API. For the broader question of what belongs in the spec, see Spec Authoring.
How they fit together
defineSpec(...) collects resources. Each resource contains an operations array. Each operation defines one HTTP contract.
A spec with multiple resources makes the grouping visible:
import { defineSpec } from "@rexeus/typeweaver-core";
import { GetTodoDefinition, CreateTodoDefinition } from "./todo/operations";
import { GetAccountDefinition, UpdateAccountDefinition } from "./account/operations";
export const spec = defineSpec({
resources: {
todo: {
operations: [GetTodoDefinition, CreateTodoDefinition],
},
account: {
operations: [GetAccountDefinition, UpdateAccountDefinition],
},
},
});
This produces two separate output folders, each with their own client, router, and type files:
generated/
├── todo/
│ ├── TodoClient.ts
│ ├── TodoRouter.ts
│ ├── GetTodoRequest.ts
│ └── ...
├── account/
│ ├── AccountClient.ts
│ ├── AccountRouter.ts
│ ├── GetAccountRequest.ts
│ └── ...
├── responses/
└── lib/
For how a single operation is authored in detail, see Spec Authoring and First Operation.
Why resources matter
Resources are not just cosmetic. They shape the generated output:
- clients are grouped by resource, such as
TodoClient - server integrations are grouped by resource, such as
TodoHonoorTodoRouter - request and response files stay easier to find when related operations live together
If every operation is shoved into one large resource, the generated folder becomes harder to scan. If related operations are split across too many tiny resources, the API becomes harder to understand. A practical default is: one resource per domain area your developers already recognize.
Folder structure is flexible
You can keep your spec in one file or split it across many files. Typeweaver does not require a specific folder layout.
What matters is:
- your spec entrypoint exports the
defineSpec(...)result - the resource map inside that spec is correct
That means all of these approaches are valid:
api/spec/index.tsapi/spec/todo/GetTodoDefinition.tsapi/spec/todo/CreateTodoDefinition.tsapi/spec/shared/responses.ts
Typeweaver cares about the spec entrypoint and the resource map, not about your folders.
Keep names stable
Two names deserve extra care:
operationIdvalues should be deliberate and stable- response names should also be deliberate and stable
Those names show up in generated code, so changing them later is usually a real API change for your own codebase.