Mastering Fastify: A Guide to Server-Side Validation Techniques
Written on
Chapter 1: Introduction to Fastify
Fastify is a lightweight framework designed for building backend applications in Node.js. In this article, we will explore the process of developing backend apps using Fastify's Fluent Schema for request validation.
To validate the content of incoming requests, we can utilize the fluent-schema module within our Fastify application. Below is a basic example of how we can set this up:
const fastify = require('fastify')({});
const S = require('fluent-schema');
const MY_KEYS = {
KEY1: 'ONE',
KEY2: 'TWO',
};
const bodyJsonSchema = S.object()
.prop('someKey', S.string())
.prop('someOtherKey', S.number())
.prop('requiredKey', S.array().maxItems(3).items(S.integer()).required())
.prop('nullableKey', S.mixed([S.TYPES.NUMBER, S.TYPES.NULL]))
.prop('multipleTypesKey', S.mixed([S.TYPES.BOOLEAN, S.TYPES.NUMBER]))
.prop('multipleRestrictedTypesKey', S.oneOf([S.string().maxLength(5), S.number().minimum(10)]))
.prop('enumKey', S.enum(Object.values(MY_KEYS)))
.prop('notTypeKey', S.not(S.array()));
const queryStringJsonSchema = S.object()
.prop('name', S.string())
.prop('excitement', S.integer());
const paramsJsonSchema = S.object()
.prop('par1', S.string())
.prop('par2', S.integer());
const headersJsonSchema = S.object()
.prop('x-foo', S.string().required());
const schema = {
body: bodyJsonSchema,
querystring: queryStringJsonSchema,
params: paramsJsonSchema,
headers: headersJsonSchema,
};
fastify.post('/', { schema }, function (req, reply) {
reply.send('success');
});
const start = async () => {
try {
await fastify.listen(3000, '0.0.0.0');} catch (err) {
fastify.log.error(err);
process.exit(1);
}
};
start();
In this code snippet, we define a JSON schema for the request body. The S.object() method is employed to enable validation for objects, while the prop method specifies the properties to validate. For instance, S.string() confirms that a property is of string type, and S.array() ensures that a property is an array. The maxItems method checks the maximum number of elements within an array, while S.oneOf allows specifying multiple valid types for a property. Additionally, S.enum validates that a property is an enumeration, utilizing an array of strings for the possible values.
When a request is made with content that does not conform to the defined schema, an error will be triggered.
Section 1.1: Reusing Schemas
To enhance efficiency, schemas can be reused by assigning them an ID with the id method. Here's an example:
const fastify = require('fastify')({});
const S = require('fluent-schema');
const addressSchema = S.object()
.id('#address')
.prop('line1').required()
.prop('line2')
.prop('country').required()
.prop('city').required()
.prop('zip').required();
const commonSchemas = S.object()
.id('app')
.definition('addressSchema', addressSchema);
fastify.addSchema(commonSchemas);
const bodyJsonSchema = S.object()
.prop('home', S.ref('app#address')).required()
.prop('office', S.ref('app#/definitions/addressSchema')).required();
const schema = { body: bodyJsonSchema };
fastify.post('/', { schema }, function (req, reply) {
reply.send('success');
});
const start = async () => {
try {
await fastify.listen(3000, '0.0.0.0');} catch (err) {
fastify.log.error(err);
process.exit(1);
}
};
start();
In this example, we create an addressSchema and add it to a reusable schema called commonSchemas. The definition method is used to include the addressSchema, while S.ref enables referencing the schema by its ID in the code, allowing for reuse.
Chapter 2: Conclusion
In summary, the fluent-schema library allows us to implement robust request validation within our Fastify applications, significantly enhancing our backend services.
In the video titled "Fastify - Serialization & Validation," viewers can gain insights into serialization and validation techniques in Fastify applications.
The video "Creating your first node app with Fastify! Pt 2 (Schema Validation and Decorators)" provides a step-by-step guide for building a Node app using Fastify, focusing on schema validation and decorators.