Documentation
Validation and Serialization
Fastify uses a schema-based approach, and even if it is not mandatory we recommend using JSON Schema to validate your routes and serialize your outputs. Internally, Fastify compiles the schema into a highly performant function.
Validation
The route validation internally relies upon Ajv, which is a high-performance JSON schema validator. Validating the input is very easy: just add the fields that you need inside the route schema, and you are done! The supported validations are:
body
: validates the body of the request if it is a POST or a PUT.querystring
: validates the query string. This can be a complete JSON Schema object (with atype
property of'object'
and a'properties'
object containing parameters) or a simpler variation in which thetype
andproperties
attributes are forgone and the query parameters are listed at the top level (see the example below).params
: validates the route params.headers
: validates the request headers.
Example:
const schema = {
body: {
type: 'object',
properties: {
someKey: { type: 'string' },
someOtherKey: { type: 'number' }
}
},
querystring: {
name: { type: 'string' },
excitement: { type: 'integer' }
},
params: {
type: 'object',
properties: {
par1: { type: 'string' },
par2: { type: 'number' }
}
},
headers: {
type: 'object',
properties: {
'x-foo': { type: 'string' }
},
required: ['x-foo']
}
}
Note that Ajv will try to coerce the values to the types specified in your schema type
keywords, both to pass the validation and to use the correctly typed data afterwards.
Schema Compiler
The schemaCompiler
is a function that returns a function that validates the body, url parameters, headers, and query string. The default schemaCompiler
returns a function that implements the ajv
validation interface. Fastify uses it internally to speed the validation up.
If you want to change the default options of the ajv
instance, you can pass the ajv
option to Fastify. The options are described in the Ajv documentation.
const fastify = require('fastify')({
ajv: {
removeAdditional: true,
useDefaults: true,
coerceTypes: true
}
})
But maybe you want to change the validation library. Perhaps you like Joi
. In this case, you can use it to validate the url parameters, body, and query string!
const Joi = require('joi')
fastify.post('/the/url', {
schema: {
body: Joi.object().keys({
hello: Joi.string().required()
}).required()
},
schemaCompiler: schema => data => Joi.validate(data, schema)
})
In that case the function returned by schemaCompiler
returns an object like:
error
: filled with an instance ofError
or a string that describes the validation errorvalue
: the coerced value that passed the validation
Serialization
Usually you will send your data to the clients via JSON, and Fastify has a powerful tool to help you, fast-json-stringify, which is used if you have provided an output schema in the route options. We encourage you to use an output schema, as it will increase your throughput by 100-400% depending on your payload and will prevent accidental disclosure of sensitive information.
Example:
const schema = {
response: {
200: {
type: 'object',
properties: {
value: { type: 'string' },
otherValue: { type: 'boolean' }
}
}
}
}
As you can see, the response schema is based on the status code. If you want to use the same schema for multiple status codes, you can use '2xx'
, for example:
const schema = {
response: {
'2xx': {
type: 'object',
properties: {
value: { type: 'string' },
otherValue: { type: 'boolean' }
}
},
201: {
type: 'object',
properties: {
value: { type: 'string' }
}
}
}
}
If you need a custom serializer in a very specific part of your code, you can always set one with reply.serializer(...)
.