Last active
December 28, 2023 11:52
-
-
Save raynirola/d4fdb99f49f377b592bb0f4e1f615b68 to your computer and use it in GitHub Desktop.
Higher Order Function that wraps Next Api handler with Zod validation library, handles errors as well.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { ZodError, ZodTypeAny, z } from 'zod' | |
import type { NextApiHandler, NextApiRequest, NextApiResponse } from 'next' | |
interface WithZodArgs<T> { | |
schema: T | |
method?: NextApiRequest['method'] | |
} | |
interface ZodRequest<T> extends NextApiRequest { | |
body: T | |
} | |
export interface NextApiHandlerWithZod<T extends ZodTypeAny> { | |
(req: ZodRequest<z.infer<T>>, res: NextApiResponse): Promise<void> | |
} | |
interface WithZod { | |
<T extends ZodTypeAny>(handler: NextApiHandlerWithZod<T>, options: WithZodArgs<T>): NextApiHandler | |
} | |
const withZod: WithZod = (handler, options) => async (req, res) => { | |
const { schema, method } = options | |
if (method && req.method !== method) { | |
return res | |
.setHeader('Allow', method) | |
.status(405) | |
.json({ | |
name: 'MethodNotAllowed', | |
message: `Cannot ${req.method} ${req.url}` | |
}) | |
} | |
try { | |
await schema.parseAsync(req.body) | |
return handler(req, res) | |
} catch (error) { | |
if (error instanceof ZodError<typeof schema._type>) { | |
return res.status(400).json({ | |
name: 'ValidationError', | |
errors: (error as ZodError<typeof schema._type>).formErrors.fieldErrors | |
}) | |
} | |
} | |
} | |
export default withZod |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment