Zod Express validator
❗️ This package is now a part of Zodyac. Please consider using @zodyac/express instead.
This package provides a set of usefull Express tools for REST request validation with zod (body, parameters and query) based on Matt Pocock's (💜) solution.
Installation
As simple as:
npm i @bebrasmell/zod-express
Usage
Validating body
Define your request body schema:
import { z } from 'zod';
const zBody = z.object({
});
Create an endpoint using CheckBody
function:
const my_endpoint = CheckBody(zBody, (req, res) => {
const body = req.body;
});
Validating parameters
You can also parse your request parameters using CheckParams
:
const my_endpoint = CheckParams(zParams, (req, res) => {
const params = req.params;
});
Validating query parameters
And query parameters using CheckQuery
:
const my_endpoint = CheckQuery(zQuery, (req, res) => {
const query = req.query;
});
As you can see, req.body, req.params and req.query are inferring types from your zod schema.
Please remember that Express
params and query parameters are always strings. If you want to parse them to other types, you have to do it manually.
Validating all at once
But what if... We want to validate all of them at once? No problem, just use Check
:
const my_endpoint = Check({
body: zBody,
params: zParams,
query: zQuery
}, (req, res) => {
const body = req.body;
const params = req.params;
const query = req.query;
});
Error handling
If validation fails, Check
, CheckBody
, CheckParams
and CheckQuery
will automatically send 406
response with error message. If you want to handle errors yourself, you can use ValidationOptions
:
const my_error_handler: ze.ValidationOptions = {
errorCode: 400,
errorHandler: (req, res, error) => {
const error_message = error.errors[0].message;
}
};
const my_endpoint = Check({
body: zBody,
params: zParams,
query: zQuery
}, (req, res) => {
const body = req.body;
const params = req.params;
const query = req.query;
}, my_error_handler);
ValidationOptions
interface:
type ErrorHandler = (req: Request, res: Response, error: z.ZodError) => void;
interface ValidationOptions {
errorCode?: number;
errorHandler?: ErrorHandler;
}
Middleware
If you prefer to validate your requests aside from your endpoints logic, you can use zem.Body
, zem.Params
, zem.Query
or zem.Check
middleware:
import { zem } from '@bebrasmell/zod-express';
const my_endpoint = (req: Request, res: Response) => {
const body = req.body;
const params = req.params;
const query = req.query;
};
app.post('/my_endpoint', zem.Body(zBody), my_endpoint);
app.get('/my_endpoint/:id', zem.Params(zParams), my_endpoint);
app.get('/my_endpoint', zem.Query(zQuery), my_endpoint);
app.put('/my_endpoint', zem.Check({
body: zBody,
params: zParams,
query: zQuery
}), my_endpoint);
In this case your req.body, req.params and req.query will be any
. If you want to use types, you have to specify them manually or use CheckBody, CheckParams, CheckQuery or Check.
Experimental: decorators
You can also use decorators to validate your requests. Just add @ValidateBody
, @ValidateParams
, @ValidateQuery
or @Validate
to your endpoint function:
export class Example {
@ValidateBody(zBody)
public static my_endpoint(req: Request, res: Response) {
const body = req.body as z.infer<typeof zBody>;
}
}
Due to the limitations of TypeScript decorators, you have to specify the type of req.body manually.
License
MIT