Schema
Schema is used to define the strict type for the Elysia handler.
Schema is not an event but a value used in a validation event to strictly type and validate an incoming request and outgoing response.
The schema consists of:
body - validate incoming body.
query - validate query string or URL parameters.
params - validate path parameters.
header - validate request's headers.
response - validate response type.
detail - Explicitly define what a route can do, see (creating documentation ) for more explanation.
Schema is defined as:
Locally: in a handler
Globally: limits to the scope
Local Schema
Local schema tied to a specific route in a local handler.
To define a schema, import t
, a schema builder re-exported from @sinclair/typebox
:
import { Elysia , t } from "elysia" ;
new Elysia ( ) . post ( "/mirror" , ( { body } ) => body , {
body : t . Object ( {
username : t . String ( ) ,
password : t . String ( ) ,
} ) ,
} ) ;
This will strictly validate the incoming body and infer body type in the handler as:
// Inferred type
interface Body {
username : string ;
password : string ;
}
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.
Global and scope
The global schema will define all types within the scope of a handler.
app . guard (
{
response : t . String ( ) ,
} ,
app =>
app
. get ( "/" , ( ) => "Hi" )
// Invalid: will throw error
. get ( "/invalid" , ( ) => 1 )
) ;
The global type will be overwritten by the nearest schema to the handler.
In other words, the inherited schema is rewritten within the inner scope.
app . guard (
{
response : t . String ( ) ,
} ,
app =>
app . guard (
{
response : t . Number ( ) ,
} ,
app =>
app
// Invalid: will throw an error
. get ( "/" , ( ) => "Hi" )
. get ( "/this-is-now-valid" , ( ) => 1 )
)
) ;
group
and guard
will define the scope limits, so the type will not get out of the scope handler.
Multiple Status Response
By default schema.response
can accept either a schema definition or a map or stringified status code with schema.
Allowing the Elysia server to define a type for each response status.
import { Elysia , t } from "elysia" ;
new Elysia ( ) . post ( "/" , ( { body } ) => doSomething ( ) , {
response : {
200 : t . Object ( {
username : t . String ( ) ,
password : t . String ( ) ,
} ) ,
400 : t . String ( ) ,
} ,
} ) ;
Reference Models
Sometimes you might find yourself reusing the same type multiple times.
Using reference models , you can name your model and use it by referencing the name:
import { Elysia } from "elysia" ;
const app = new Elysia ( )
. model ( {
sign : t . Object ( {
username : t . String ( ) ,
password : t . String ( ) ,
} ) ,
} )
. post ( "/sign-in" , ( { body } ) => body , {
// with auto-completion for existing model name
body : "sign" ,
response : "sign" ,
} ) ;
For more explanation, see Reference Models .