You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs(en): realign guides to v0.15 context namespace API
- Consolidate response helpers into download and empty
- Document ctx.get, ctx.set, and ctx.send namespaces
- Document timeout 503 and template limit 400 statuses
- Drop ctx.state in favor of signed session and validated
- Move worker pool guide to recipes
- Remove wildcard wording from route patterns description
- Rename lifecycle events and add security event group
- Rename routesDir to routes.directory across config
- Rename WrapMware to Wrap.apply and Validator.read to ctx.get.validated
Copy file name to clipboardExpand all lines: docs/by-design/bearer-auth.md
+17-20Lines changed: 17 additions & 20 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,24 +22,23 @@ Bearer is the opposite. The token format, the signature, and the trust source al
22
22
23
23
A token guard is a small composition over parts that already ship:
24
24
25
-
-**Read the header** - [`ctx.header('authorization')`](/core-concepts/context-object#request-data-access) returns the raw `Authorization` value.
25
+
-**Read the header** - [`ctx.get.header('authorization')`](/core-concepts/context-object#ctx-get-header-key) returns the raw `Authorization` value.
26
26
-**Run early** - [global middleware](/middleware/global) runs before route handlers and can stop a request by returning a `Response`.
27
27
-**Reject cleanly** - [`ctx.handleError(401, ...)`](/core-concepts/context-object#error-handling) routes through [`router.catch()`](/error-handling/object-details) when one is set.
28
-
-**Carry the result** - [`ctx.state`](/core-concepts/context-object#sharing-state) hands the decoded identity to the handler downstream.
28
+
-**Carry the result** - [`ctx.set.session(...)`](/core-concepts/context-object#ctx-set-session-data) signs the decoded identity into a cookie the handler reads back, covered in [session middleware](/middleware/session).
29
29
30
30
## A Bearer Guard
31
31
32
-
This middleware pulls the token out of the header, verifies it, and stores the result for later handlers. The `verifyToken` placeholder stands in for the scheme of choice, a JWT check, a JWKS lookup, or an introspection call.
32
+
This middleware pulls the token out of the header, verifies it, and stores the result for later handlers. The `verifyToken` placeholder stands in for the scheme of choice, a JWT check, a JWKS lookup, or an introspection call. Storing the identity needs the [session middleware](/middleware/session) registered first.
The handler then reads the identity straight from state, with no token parsing of its own.
65
+
The handler then reads the identity straight from the session, with no token parsing of its own.
67
66
68
67
```typescript twoslash
69
68
importtype { Context } from'@neabyte/deserve'
70
69
// ---cut---
71
70
exportfunction GET(ctx:Context):Response {
72
71
// Read what the guard stored
73
-
constuserId=ctx.state.userId
74
-
returnctx.send.json({ userId })
72
+
constsession=ctx.get.session()
73
+
returnctx.send.json({ userId: session?.userId })
75
74
}
76
75
```
77
76
78
77
## Routing Failures Through One Handler
79
78
80
-
The guard above returns the `401` from inside the middleware. To send every auth failure through one place, wrap the middleware with [`WrapMware`](/middleware/global#wrapping-middleware-with-error-handling) and throw on rejection, then shape the reply with [`router.catch()`](/error-handling/object-details).
79
+
The guard above returns the `401` from inside the middleware. To send every auth failure through one place, wrap the middleware with [`Wrap.apply`](/middleware/global#wrapping-middleware-with-error-handling) and throw on rejection, then shape the reply with [`router.catch()`](/error-handling/object-details).
@@ -121,22 +119,21 @@ This is the same wrapping pattern [Basic Auth](/middleware/basic-auth) uses inte
121
119
A token guard often belongs on an API prefix while public pages stay open. Path-specific middleware scopes the check to one prefix, the same form shown in [global middleware](/middleware/global#path-specific-middleware).
Copy file name to clipboardExpand all lines: docs/by-design/compress.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -56,15 +56,15 @@ To keep one response uncompressed, set a header the runtime treats as a stop sig
56
56
importtype { Context } from'@neabyte/deserve'
57
57
// ---cut---
58
58
exportfunction GET(ctx:Context):Response {
59
-
// Block any layer from rewriting the body
60
-
ctx.setHeader('Cache-Control', 'no-transform')
59
+
// Block any layer from rewriting body
60
+
ctx.set.header('Cache-Control', 'no-transform')
61
61
returnctx.send.json({
62
62
message: 'sent verbatim'
63
63
})
64
64
}
65
65
```
66
66
67
-
Setting headers through [`ctx.setHeader`](/core-concepts/context-object#response-headers) is the same path used everywhere else, so this opt-out reads like any other header.
67
+
Setting headers through [`ctx.set.header`](/core-concepts/context-object#ctx-set-header-key-value) is the same path used everywhere else, so this opt-out reads like any other header.
Copy file name to clipboardExpand all lines: docs/by-design/https-redirect.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -38,21 +38,21 @@ await router.serve(8000)
38
38
39
39
## Reading the Real Scheme
40
40
41
-
When the app does need to know whether the client used HTTPS, the answer rides in a forwarded header the proxy sets, not in the local connection. A trusted proxy adds [`X-Forwarded-Proto`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto), read through [`ctx.header`](/core-concepts/context-object#request-data-access).
41
+
When the app does need to know whether the client used HTTPS, the answer rides in a forwarded header the proxy sets, not in the local connection. A trusted proxy adds [`X-Forwarded-Proto`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto), read through [`ctx.get.header`](/core-concepts/context-object#ctx-get-header-key).
42
42
43
43
```typescript twoslash
44
44
importtype { Context } from'@neabyte/deserve'
45
45
// ---cut---
46
46
exportfunction GET(ctx:Context):Response {
47
47
// Scheme the client actually used
48
-
const proto =ctx.header('x-forwarded-proto') ??'http'
48
+
const proto =ctx.get.header('x-forwarded-proto') ??'http'
49
49
returnctx.send.json({
50
50
secure: proto==='https'
51
51
})
52
52
}
53
53
```
54
54
55
-
Trust this header only behind a proxy configured through [`trustProxy`](/getting-started/server-configuration#client-ip-resolution), the same trust boundary [`ctx.ip`](/by-design/request-id#the-ip-is-the-source-of-truth) relies on. An untrusted client can set any header, so the value means nothing without that boundary.
55
+
Trust this header only behind a proxy configured through [`trustProxy`](/getting-started/server-configuration#client-ip-resolution), the same trust boundary [`ctx.get.ip()`](/core-concepts/context-object#ctx-get-ip-options) relies on. An untrusted client can set any header, so the value means nothing without that boundary.
Copy file name to clipboardExpand all lines: docs/by-design/locale-redirect.md
+7-6Lines changed: 7 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,14 +14,14 @@ Language choice is a product decision, not a transport rule. Which locales exist
14
14
15
15
## Reading the Preference
16
16
17
-
The browser sends its language list in the [`Accept-Language`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language) header, read through [`ctx.header`](/core-concepts/context-object#request-data-access). A small match against the locales the app supports gives the target, then [`ctx.send.redirect`](/response/redirect) sends the visitor there.
17
+
The browser sends its language list in the [`Accept-Language`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language) header, read through [`ctx.get.header`](/core-concepts/context-object#ctx-get-header-key). A small match against the locales the app supports gives the target, then [`ctx.send.redirect`](/response/redirect) sends the visitor there.
@@ -37,7 +37,7 @@ A 302 keeps the redirect temporary, so a later visit can still be matched again.
37
37
38
38
## Sharing the Choice With Later Routes
39
39
40
-
When several routes need the resolved locale, middleware can resolve it once and store it in [`ctx.state`](/core-concepts/context-object#sharing-state) instead of redirecting, so each handler reads the same value.
40
+
When several routes need the resolved locale, middleware can resolve it once and store it in the signed [session](/middleware/session) instead of redirecting, so each handler reads the same value through `ctx.get.session()`.
The redirect form sends the visitor to a localized URL, while the state form keeps one URL and passes the locale inward. Both stay in plain route files, so the rule is where the language matters and nowhere else.
61
+
The redirect form sends the visitor to a localized URL, while the session form keeps one URL and passes the locale inward. Both stay in plain route files, so the rule is where the language matters and nowhere else.
Copy file name to clipboardExpand all lines: docs/by-design/method-override.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,15 +22,15 @@ Deserve also routes on the real `req.method`, which a handler cannot rewrite mid
22
22
23
23
## Every Method Is a Route
24
24
25
-
A route file exports one function per method, and the name is the method. There is no table to register and no verb to translate. A file like `items/[id].ts` reads its `id` from the path through [`ctx.param`](/core-concepts/context-object#request-data-access).
25
+
A route file exports one function per method, and the name is the method. There is no table to register and no verb to translate. A file like `items/[id].ts` reads its `id` from the path through [`ctx.get.param`](/core-concepts/context-object#ctx-get-param-key).
26
26
27
27
```typescript twoslash
28
28
importtype { Context } from'@neabyte/deserve'
29
29
// ---cut---
30
30
// Read one item by id
31
31
exportfunction GET(ctx:Context):Response {
32
32
returnctx.send.json({
33
-
id: ctx.param('id')
33
+
id: ctx.get.param('id')
34
34
})
35
35
}
36
36
@@ -67,7 +67,7 @@ await fetch(
67
67
)
68
68
```
69
69
70
-
Building stateless or stateful is the same move, just drop the files. A stateless REST endpoint is a handler that reads the request and replies, while a stateful flow adds the [session middleware](/middleware/session) and reads per-user data from [`ctx.state`](/core-concepts/context-object#sharing-state). The method stays real either way, with nothing to disguise on the way in.
70
+
Building stateless or stateful is the same move, just drop the files. A stateless REST endpoint is a handler that reads the request and replies, while a stateful flow adds the [session middleware](/middleware/session) and reads per-user data through `ctx.get.session()`. The method stays real either way, with nothing to disguise on the way in.
71
71
72
72
A full REST or RESTful API falls out of this with no extra wiring. The verbs already line up with the actions, `GET` to read, `POST` to create, `PUT` and `PATCH` to update, `DELETE` to remove, so a resource is just a route file with those handlers. The behavior reads the same across every endpoint, which is what makes the whole API feel seamless.
0 commit comments