Configuration object containing Zod schemas for different request parts
Optional
body?: ZodType<any, ZodTypeDef, any>Optional Zod schema for validating request body data
Optional
params?: ZodType<any, ZodTypeDef, any>Optional Zod schema for validating URL parameters
Optional
query?: ZodType<any, ZodTypeDef, any>Optional Zod schema for validating query string parameters
Express middleware function that performs the validation
// Validate only request body
const userSchema = z.object({
name: z.string().min(1, 'Name is required'),
email: z.string().email('Invalid email format'),
age: z.number().int().min(13, 'Must be at least 13 years old')
});
router.post('/users', validate({ body: userSchema }), userController.create);
// Validate URL parameters only
const paramSchema = z.object({
id: z.string().uuid('Invalid user ID format'),
courseId: z.string().uuid('Invalid course ID format')
});
router.get('/users/:id/courses/:courseId', validate({ params: paramSchema }), handler);
// Validate query parameters with transformations
const querySchema = z.object({
page: z.string().transform(val => parseInt(val, 10)).pipe(z.number().int().min(1)),
limit: z.string().transform(val => parseInt(val, 10)).pipe(z.number().int().min(1).max(100)),
search: z.string().optional(),
sortBy: z.enum(['name', 'createdAt', 'updatedAt']).optional()
});
router.get('/courses', validate({ query: querySchema }), courseController.list);
// Comprehensive validation for complex endpoints
const updateCourseSchema = {
params: z.object({
id: z.string().uuid('Invalid course ID')
}),
body: z.object({
title: z.string().min(1, 'Title is required').max(200, 'Title too long'),
description: z.string().optional(),
isPublished: z.boolean().optional(),
tags: z.array(z.string()).max(10, 'Too many tags').optional()
}),
query: z.object({
notify: z.string().transform(val => val === 'true').pipe(z.boolean()).optional()
})
};
router.put('/courses/:id', validate(updateCourseSchema), courseController.update);
// Nested object validation
const lessonSchema = z.object({
title: z.string().min(1),
content: z.object({
type: z.enum(['video', 'text', 'interactive']),
data: z.object({
url: z.string().url().optional(),
text: z.string().optional(),
exercises: z.array(z.object({
question: z.string(),
answer: z.string()
})).optional()
})
})
});
router.post('/lessons', validate({ body: lessonSchema }), lessonController.create);
Primary validation middleware factory for comprehensive request data validation
Creates Express middleware that validates incoming HTTP requests against Zod schemas for body, parameters, and query string data. This function serves as the core validation mechanism for the WayrApp backend API, ensuring all incoming data conforms to expected structures before reaching route handlers and business logic layers.
The middleware performs validation in a specific order: body, parameters, then query parameters. Each validation step transforms and validates the corresponding request data, automatically coercing types where appropriate (e.g., string to number conversions). If validation succeeds, the validated and transformed data replaces the original request data, ensuring type safety throughout the request lifecycle.
When validation fails, the middleware automatically forwards Zod validation errors to the global error handler, which transforms them into standardized API error responses. This ensures consistent error formatting and proper HTTP status codes for all validation failures.
The function is designed for high performance with minimal overhead, utilizing Zod's efficient parsing engine and avoiding unnecessary data copying. It supports complex nested schemas, conditional validation, custom transformations, and all Zod validation features.
Security features include automatic sanitization of input data, prevention of prototype pollution attacks through safe object parsing, and protection against type confusion attacks by enforcing strict schema adherence. The middleware also includes safeguards against denial-of-service attacks through efficient validation algorithms.