End-to-End Walkthrough
This is the short version of the full Typeweaver loop:
- write a spec
- generate code
- implement one server handler
- call it with the generated client
1. Write the spec
Create api/spec/index.ts:
import {
defineOperation,
defineResponse,
defineSpec,
HttpMethod,
HttpStatusCode,
} from "@rexeus/typeweaver-core";
import { z } from "zod";
const todoSchema = z.object({
id: z.string(),
title: z.string(),
completed: z.boolean(),
});
const GetTodoDefinition = defineOperation({
operationId: "GetTodo",
method: HttpMethod.GET,
summary: "Get a single todo by ID",
path: "/todos/:todoId",
request: {
param: z.object({
todoId: z.string(),
}),
},
responses: [
defineResponse({
name: "GetTodoSuccess",
statusCode: HttpStatusCode.OK,
description: "Todo retrieved successfully",
body: todoSchema,
}),
],
});
export const spec = defineSpec({
resources: {
todo: {
operations: [GetTodoDefinition],
},
},
});
2. Generate code
npx typeweaver generate --input ./api/spec/index.ts --output ./api/generated --plugins clients,server
3. Implement one server handler and start the server
Create server.ts:
import {
TodoRouter,
TypeweaverApp,
createGetTodoSuccessResponse,
} from "./api/generated";
const todoRouter = new TodoRouter({
requestHandlers: {
async handleGetTodoRequest(request) {
return createGetTodoSuccessResponse({
body: {
id: request.param.todoId,
title: "Ship docs",
completed: false,
},
});
},
},
});
const app = new TypeweaverApp();
app.route("/api", todoRouter);
Now start the server. TypeweaverApp exposes a standard fetch handler, so it works natively in Fetch API runtimes:
// Deno
Deno.serve({ port: 3000 }, app.fetch);
// Bun
Bun.serve({ port: 3000, fetch: app.fetch });
For Node.js, use the generated nodeAdapter:
import { createServer } from "node:http";
import { nodeAdapter } from "./api/generated/lib/server";
createServer(nodeAdapter(app)).listen(3000);
4. Call it with the generated client
import { GetTodoRequestCommand, TodoClient } from "./api/generated";
const client = new TodoClient({
baseUrl: "http://localhost:3000/api",
});
const response = await client.send(
new GetTodoRequestCommand({
param: {
todoId: "todo_123",
},
}),
);
if (response.type === "GetTodoSuccess") {
console.log(response.body.title); // "Ship docs"
}
What this proves
One spec now drives:
- the request and response types
- the runtime validators
- the server handler shape
- the generated client call
That is the core Typeweaver workflow. From here, go deeper with Generate and Run, Clients, or Server Plugin.