Skip to content

Commit 522c540

Browse files
committed
docs: document HTTP action route trees
Update consumer documentation for the user-visible routing changes after v2.0.1. The README now points evaluators at the rouzer/http action API and shows the new direct client call shape, while docs/context.md explains resources, migration from method-map routes, and current gotchas. Refresh public TSDoc for low-level route() descriptors so generated declarations no longer claim those method-map routes are accepted by router/client route tree registration.
1 parent d5cacb8 commit 522c540

4 files changed

Lines changed: 289 additions & 101 deletions

File tree

README.md

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
# Rouzer
22

3-
Rouzer lets you declare a route once and share its TypeScript types and Zod
4-
validation between a Hattip-compatible server and a typed fetch client.
3+
Rouzer lets you declare an HTTP route tree once and share its TypeScript types
4+
and Zod validation between a Hattip-compatible server and a typed fetch client.
55

66
## What it does
77

8-
A Rouzer route declaration defines a URL pattern, method schemas, and optional
9-
response type once, then reuses that contract to:
8+
A Rouzer HTTP route tree defines URL patterns, named actions, method schemas, and
9+
optional response types once, then reuses that contract to:
1010

1111
- validate client arguments before `fetch`
1212
- match and validate server requests before handlers run
1313
- type handler context from path, query/body, headers, and middleware
14-
- attach typed client shorthand methods such as `client.helloRoute.GET(...)`
14+
- attach typed client action functions such as `client.profiles.get(...)`
1515

1616
Rouzer optimizes for shared TypeScript route modules over language-agnostic API
1717
schemas or generated SDKs.
@@ -20,10 +20,10 @@ schemas or generated SDKs.
2020

2121
Use Rouzer if:
2222

23-
- your server and client can import the same TypeScript route declarations
23+
- your server and client can import the same TypeScript route tree
2424
- you want Zod request validation on both sides of an HTTP boundary
2525
- a Hattip-compatible handler fits your server runtime
26-
- you prefer a small routing/client contract over a full web framework
26+
- you prefer named resource/action functions over a generated client class
2727

2828
Consider something else if:
2929

@@ -41,49 +41,48 @@ Consider something else if:
4141
- Zod v4 or newer
4242
- a Hattip adapter when using `createRouter(...)`
4343
- a Fetch API implementation when using `createClient(...)`
44-
- an absolute `baseURL` for pathname route patterns
44+
- an absolute `baseURL` for generated client URLs
4545

4646
## Installation
4747

4848
```sh
4949
pnpm add rouzer zod
5050
```
5151

52-
Import the public API from the root package:
52+
Import the primary API from the root package and declare routes through the HTTP
53+
subpath:
5354

5455
```ts
55-
import { $type, chain, createClient, createRouter, route } from 'rouzer'
56+
import { $type, chain, createClient, createRouter } from 'rouzer'
57+
import * as http from 'rouzer/http'
5658
```
5759

5860
`chain` is re-exported from `alien-middleware` for typed server middleware.
5961

6062
## Quick example
6163

62-
This example shows the core loop: one route contract defines validation, server
63-
handler types, and the typed client call.
64+
This example shows the core loop: one HTTP action contract defines validation,
65+
server handler types, and the typed client call.
6466

6567
```ts
6668
import * as z from 'zod'
67-
import { $type, createClient, createRouter, route } from 'rouzer'
68-
69-
export const helloRoute = route('hello/:name', {
70-
GET: {
71-
query: z.object({
72-
excited: z.optional(z.boolean()),
73-
}),
74-
response: $type<{ message: string }>(),
75-
},
69+
import { $type, createClient, createRouter } from 'rouzer'
70+
import * as http from 'rouzer/http'
71+
72+
export const hello = http.get('hello/:name', {
73+
query: z.object({
74+
excited: z.optional(z.boolean()),
75+
}),
76+
response: $type<{ message: string }>(),
7677
})
7778

78-
export const routes = { helloRoute }
79+
export const routes = { hello }
7980

8081
export const handler = createRouter({ basePath: 'api/' }).use(routes, {
81-
helloRoute: {
82-
GET(ctx) {
83-
return {
84-
message: `Hello, ${ctx.path.name}${ctx.query.excited ? '!' : '.'}`,
85-
}
86-
},
82+
hello(ctx) {
83+
return {
84+
message: `Hello, ${ctx.path.name}${ctx.query.excited ? '!' : '.'}`,
85+
}
8786
},
8887
})
8988

@@ -92,20 +91,20 @@ const client = createClient({
9291
routes,
9392
})
9493

95-
const { message } = await client.helloRoute.GET({
94+
const { message } = await client.hello({
9695
path: { name: 'world' },
9796
query: { excited: true },
9897
})
9998
```
10099

101-
`handler` can be mounted with any Hattip adapter. Client calls validate route
102-
arguments before `fetch`; server handlers validate matched path, query, headers,
103-
and JSON bodies before your handler runs.
100+
`handler` can be mounted with any Hattip adapter. Client action calls validate
101+
route arguments before `fetch`; server handlers validate matched path, query,
102+
headers, and JSON bodies before your handler runs.
104103

105104
## Documentation
106105

107-
- [Concepts and API selection](docs/context.md)
106+
- [Concepts, API selection, and v2.0.1 migration notes](docs/context.md)
108107
- [Runnable shared-route example](examples/basic-usage.ts)
109108
- Generated declarations in the published package provide the exact signatures
110-
for every public export.
109+
for every public export, including the `rouzer/http` subpath.
111110
- Public TSDoc in `src/` owns symbol-level behavior and option details.

0 commit comments

Comments
 (0)