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, or auth
  • an operation is one contract such as GetTodo or CreateTodo

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 TodoHono or TodoRouter
  • 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.ts
  • api/spec/todo/GetTodoDefinition.ts
  • api/spec/todo/CreateTodoDefinition.ts
  • api/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:

  • operationId values 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.

Was this page helpful?