Gathering detailed insights and metrics for zod-express
Gathering detailed insights and metrics for zod-express
Gathering detailed insights and metrics for zod-express
Gathering detailed insights and metrics for zod-express
express-zod-api
A Typescript framework to help you get an API server up and running with I/O schema validation and custom middlewares in minutes.
zod-express-middleware
Express middleware to validate requests using zod schema's.
@zodios/express
Typescript express server
@shrub/express-zod
Express module that provides error middleware for zod validation errors.
Express middleware to validate requests using zod schema's(with Custom Error Handler).
npm install zod-express
Typescript
Module System
Node Version
NPM Version
73.2
Supply Chain
28.1
Quality
73
Maintenance
100
Vulnerability
100
License
TypeScript (99.02%)
JavaScript (0.98%)
Total Downloads
78,350
Last Day
833
Last Week
4,881
Last Month
11,694
Last Year
51,469
MIT License
2 Stars
96 Commits
1 Forks
1 Branches
2 Contributors
Updated on Oct 25, 2023
Minified
Minified + Gzipped
Latest Version
0.0.8
Package Id
zod-express@0.0.8
Unpacked Size
33.56 kB
Size
7.12 kB
File Count
5
NPM Version
9.5.0
Node Version
18.15.0
Published on
Apr 06, 2023
Cumulative downloads
Total Downloads
Last Day
325%
833
Compared to previous day
Last Week
100%
4,881
Compared to previous week
Last Month
83.3%
11,694
Compared to previous month
Last Year
94%
51,469
Compared to previous year
This was forked from zod-express-middleware
.
Middleware for express that uses zod to make requests type-safe.
This package relies on zod, express and @types/express. These have been added as peer dependencies so they can be upgraded independently of this package.
zod-express can be installed using:
npm install zod-express
This package provides the validateRequest
and validateRequestAsync
function, which can be used to validate the .body
, .query
and .params
properties of an Express Request
. Separate functions for each of these are also provided (validateRequestBody
, validateRequestQuery
, validateRequestParams
and the async functions validateRequestBodyAsync
, validateRequestQueryAsync
, validateRequestParamsAsync
).
Basic example:
1import { validateRequest } from 'zod-express'; 2import { z } from 'zod'; 3 4// app is an express app 5app.get("/", validateRequest({ 6 body: z.object({ 7 bodyKey: z.number(), 8 }), 9 }), (req, res) => { 10 // req.body is now strictly-typed and confirms to the zod schema above. 11 // req.body has type { bodyKey: number }; 12 return res.json({message: "Validation for body passed"}); 13 } 14);
A full example of using validateRequest
in a tiny Express app:
Full example:
1import express from 'express'; 2import { validateRequest } from 'zod-express'; 3import { z } from 'zod'; 4 5// Create an express app 6const app = express(); 7 8// Define an endpoint using express, zod and zod-express 9app.get("/:urlParameter/", validateRequest({ 10 params: z.object({ 11 urlParameter: z.string(), 12 }), 13 body: z.object({ 14 bodyKey: z.number(), 15 }), 16 query: z.object({ 17 queryKey: z.string().length(64), 18 }), 19 }), (req, res) => { 20 // req.params, req.body and req.query are now strictly-typed and confirm to the zod schema's above. 21 // req.params has type { urlParameter: string }; 22 // req.body has type { bodyKey: number }; 23 // req.query has type { queryKey: string }; 24 return res.json({message: "Validation for params, body and query passed"}); 25 } 26); 27 28// Start the express app on port 8080 29const PORT = 8080; 30app.listen(PORT, () => { 31 console.log(`Server running `); 32});
The validate*
functions do not modify the query, params or body of the Request object, they only check whether they are valid according to the provided schema's. If you want to use the result of the schema validation (for example, if you want to strip unknown keys), you can use the process*
equivalents (ie. processRequest
or processRequestBody
). These functions also accept a ZodEffects
object, which means you can use zod's built-in .transform
method:
Zod transformation example:
1import { processRequest } from 'zod-express'; 2import { z } from 'zod'; 3 4export const zodEffects = z 5 .object({ jsonString: z.string() }) 6 .refine( 7 incomingData => { 8 try { 9 return JSON.parse(incomingData.jsonString); 10 } catch (error) { 11 return false; 12 } 13 }, 14 { 15 message: '.jsonString should be a valid JSON string.', 16 }, 17 ) 18 .transform(incomingData => { 19 return z.object( { bodyKey: z.number() } ).parse(JSON.parse(incomingData.afhandelingsData)); 20 }); 21 22// app is an express app 23app.get("/", processRequest({ 24 body: zodEffects 25 }), (req, res) => { 26 // req.body is now strictly-typed and confirms to the zod schema above ( in the .transform method ). 27 // req.body has type { bodyKey: number }; 28 return res.json({message: "Validation for body passed"}); 29 } 30);
This functions accepts an object containing three optional properties:
1schemas: { 2 params? : ZodSchema, 3 query? : ZodSchema, 4 body? : ZodSchema 5}
Each is a ZodSchema
, from the zod library. The validateRequest
function checks whether each of these is present and if so, it will use it validate the corresponding property on the Express Request
object.
If validation passes, next
will be called and your request body, query and params properties will be type-safe within the endpoint.
If validation fails, a HTTP 400 response with a list of validation errors will be send to the caller. The next
function will not be called and the request will stop being processed further.
These three functions work exactly the same as validateRequest
, except they only validate a single property within the Express Request
.
The other, non-validated properties will have type any
, as if they were not modified at all. Only an example is provided for validateRequestBody
, but validateRequestQuery
and validateRequestParams
work in the same manner.
Example:
1import { validateRequestBody } from 'zod-express'; 2import { z } from 'zod'; 3 4// app is an express app 5app.get("/", validateRequestBody( 6 z.object({ 7 bodyKey: z.number(), 8 }) 9 ), (req, res) => { 10 // req.body is now strictly-typed and confirms to the zod schema above. 11 // req.body: { bodyKey: number }; 12 return res.json({ message: "Validation for body passed" }); 13 } 14);
This functions accepts an object containing three optional properties:
1schemas: { 2 params? : ZodSchema, 3 query? : ZodSchema, 4 body? : ZodSchema 5}
Each is a ZodSchema
or a ZodEffects
object, from the zod library. The processRequest
function checks whether each of these is present and if so, it will use it process the corresponding property on the Express Request
object.
If validation passes, next
will be called and your request body, query and params properties will be type-safe within the endpoint. The body, query and params object will contain the result of the (succesful) parsing by zod.
If validation fails, a HTTP 400 response with a list of validation errors will be send to the caller. The next
function will not be called and the request will stop being processed further.
These three functions work exactly the same as processRequest
, except they only process a single property within the Express Request
.
The other, non-processed properties will have type any
, as if they were not modified at all. Only an example is provided for processRequestBody
, but processRequestQuery
and processRequestParams
work in the same manner.
Example:
1import { processRequestBody } from 'zod-express'; 2import { z } from 'zod'; 3 4// app is an express app 5app.get("/", processRequestBody( 6 z.object({ 7 bodyKey: z.number(), 8 }) 9 ), (req, res) => { 10 // req.body is now strictly-typed and confirms to the zod schema above. 11 // req.body: { bodyKey: number }; 12 return res.json({ message: "Validation for body passed" }); 13 } 14);
These two functions can be used to send errors using an Express Response
to the caller of an endpoint in the same format as the validateRequest
functions. The function accepts two parameters: an ErrorListItem
and an Express Response
. The ErrorListItem
has type { type: 'Body' | 'Query' | 'Params', errors: ZodError }
.
The example below uses sendError
to emulate the functionality of validateRequestBody
.
The sendErrors
function does the same but accepts an array of ErrorListItem
objects.
Example:
1import { sendError } from 'zod-express'; 2import { z } from 'zod'; 3 4// app is an express app 5app.get("/", (req, res) => { 6 const zodSchema = z.object({bodyKey: z.number()}); 7 const result = zodSchema.safeParse(req.body); 8 if(!result.success) { 9 return sendError({type: 'Body', errors: result.error}, res); 10 } 11 return res.json({ message: "Validation passed" }); 12 } 13);
At the time of creating validator middleware you are able to pass options to the function:
This boolean value can pass the error to the next
function and you can handle the error yourself.
1import { validateRequest } from 'zod-express'; 2import { z } from 'zod'; 3 4// app is an express app 5app.get("/", validateRequest({ 6 body: z.object({ 7 bodyKey: z.number(), 8 }), 9 }, { passErrorToNext: true }), (req, res) => { 10 // req.body is now strictly-typed and confirms to the zod schema above. 11 // req.body has type { bodyKey: number }; 12 return res.json({message: "Validation for body passed"}); 13 } 14);
You can pass your custom error handler to zod-express
:
1import { validateRequest } from 'zod-express'; 2import { z } from 'zod'; 3 4// app is an express app 5app.get("/", validateRequest({ 6 body: z.object({ 7 bodyKey: z.number(), 8 }), 9 }, 10 { sendErrors: (res, errors) => { 11 res.json({ message: "Bad Request" })} 12 }), (req, res) => { 13 // req.body is now strictly-typed and confirms to the zod schema above. 14 // req.body has type { bodyKey: number }; 15 return res.json({message: "Validation for body passed"}); 16 } 17);
Besides exporting the above middleware functions, zod-express also provided several typings for usage with Express requests. Typescript is able to automatically infer the types of your request body, query and params if your endpoint definition is placed in the same file as the validation middleware, as shown above. However, if the code for your endpoint is in a separate file, typings will not be automatically available. This is where the TypedRequest
, TypedRequestBody
etc. types come in: the typeof
a ZodSchema
can be passed into the TypedRequest
, providing your function with typings. An example:
1import { Response } from 'express'; 2import { TypedRequestBody } from 'zod-express'; 3 4// bodySchema is a ZodSchema, imported from another file. 5import { bodySchema } from '../validation/requestSchemas'; 6 7// This is the endpoint code: it is not placed in the same file as the route definition and the validation middleware. 8export async function endpointCode(req: TypedRequestBody<typeof bodySchema>, res: Response) { 9 // req.body is now typed: use TypedRequestParams, TypedRequestQuery for params and query, or TypedRequest for multiple together. 10 const typedBody = req.body; 11 return res.json(typedBody); 12} 13
No vulnerabilities found.
No security vulnerabilities found.