Skip to content

Commit 96de3ea

Browse files
committed
📘 doc: remove package-lock.json
1 parent 61d7b87 commit 96de3ea

File tree

2 files changed

+143
-9164
lines changed

2 files changed

+143
-9164
lines changed

docs/concept/schema.md

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
---
2+
title: Schema - ElysiaJS
3+
head:
4+
- - meta
5+
- property: 'og:title'
6+
content: Schema - ElysiaJS
7+
8+
- - meta
9+
- name: 'description'
10+
content: Schema is a strictly typed definitions, use to infer TypeScript's type and data validation of an incoming request and outgoing response. Elysia's schema validation are based on Sinclair's TypeBox, a TypeScript library for data validation.
11+
12+
- - meta
13+
- property: 'og:description'
14+
content: Schema is a strictly typed definitions, use to infer TypeScript's type and data validation of an incoming request and outgoing response. Elysia's schema validation are based on Sinclair's TypeBox, a TypeScript library for data validation.
15+
---
16+
17+
# Schema
18+
Schema is used to define the strict type for the Elysia handler.
19+
20+
Schema is not an event but a value used in a validation event to strictly type and validate an incoming request and outgoing response.
21+
22+
The schema consists of:
23+
- body - validate incoming body.
24+
- query - validate query string or URL parameters.
25+
- params - validate path parameters.
26+
- header - validate request's headers.
27+
- response - validate response type.
28+
- detail - Explicitly define what a route can do, see ([creating documentation](/patterns/creating-documentation)) for more explanation.
29+
30+
Schema is defined as:
31+
- Locally: in a handler
32+
- Globally: limits to the scope
33+
34+
## Local Schema
35+
Local schema tied to a specific route in a local handler.
36+
37+
To define a schema, import `t`, a schema builder re-exported from `@sinclair/typebox`:
38+
```typescript
39+
import { Elysia, t } from 'elysia'
40+
41+
new Elysia()
42+
.post('/mirror', ({ body }) => body, {
43+
body: t.Object({
44+
username: t.String(),
45+
password: t.String()
46+
})
47+
})
48+
```
49+
50+
This will strictly validate the incoming body and infer body type in the handler as:
51+
```typescript
52+
// Inferred type
53+
interface Body {
54+
username: string
55+
password: string
56+
}
57+
```
58+
59+
This means that you will get strict type defining once from a schema and get inferred type to TypeScript without needing to write a single TypeScript.
60+
61+
However, if you really want to get the Typescript type, this will do, but not `Static` method of Typebox:
62+
```typescript
63+
const body = t.Object({
64+
username: t.String(),
65+
password: t.String(),
66+
});
67+
68+
type bodyTp = (typeof body)["static"]
69+
```
70+
71+
## Global and scope
72+
The global schema will define all types within the scope of a handler.
73+
74+
```typescript
75+
app.guard({
76+
response: t.String()
77+
}, app => app
78+
.get('/', () => 'Hi')
79+
// Invalid: will throw error
80+
.get('/invalid', () => 1)
81+
)
82+
```
83+
84+
The global type will be overwritten by the nearest schema to the handler.
85+
86+
In other words, the inherited schema is rewritten within the inner scope.
87+
```typescript
88+
app.guard({
89+
response: t.String()
90+
}, app => app.guard({
91+
response: t.Number()
92+
}, app => app
93+
// Invalid: will throw an error
94+
.get('/', () => 'Hi')
95+
.get('/this-is-now-valid', () => 1)
96+
)
97+
)
98+
```
99+
100+
`group` and `guard` will define the scope limits, so the type will not get out of the scope handler.
101+
102+
## Multiple Status Response
103+
By default `schema.response` can accept either a schema definition or a map or stringified status code with schema.
104+
105+
Allowing the Elysia server to define a type for each response status.
106+
107+
```typescript
108+
import { Elysia, t } from 'elysia'
109+
110+
new Elysia()
111+
.post('/', ({ body }) => doSomething(), {
112+
response: {
113+
200: t.Object({
114+
username: t.String(),
115+
password: t.String()
116+
}),
117+
400: t.String()
118+
}
119+
})
120+
```
121+
122+
## Reference Models
123+
Sometimes you might find yourself reusing the same type multiple times.
124+
125+
Using [reference models](/patterns/reference-models), you can name your model and use it by referencing the name:
126+
```typescript
127+
import { Elysia, t } from 'elysia'
128+
129+
const app = new Elysia()
130+
.model({
131+
sign: t.Object({
132+
username: t.String(),
133+
password: t.String()
134+
})
135+
})
136+
.post('/sign-in', ({ body }) => body, {
137+
// with auto-completion for existing model name
138+
body: 'sign',
139+
response: 'sign'
140+
})
141+
```
142+
143+
For more explanation, see [Reference Models](/patterns/reference-models).

0 commit comments

Comments
 (0)