mirror of
https://github.com/shadcn-ui/taxonomy
synced 2026-05-24 09:48:32 +00:00
93 lines
2.3 KiB
Text
93 lines
2.3 KiB
Text
---
|
|
title: Next.js API Routes validation using Middlewares and Yup
|
|
date: "2023-01-08"
|
|
---
|
|
|
|
## Middlewares
|
|
|
|
### withMethods
|
|
|
|
Let's start with a simple middleware to validate `request.method`.
|
|
|
|
```ts
|
|
import type { NextApiHandler, NextApiRequest, NextApiResponse } from "next"
|
|
|
|
export function withMethods(methods: string[], handler: NextApiHandler) {
|
|
return async function (request: NextApiRequest, response: NextApiResponse) {
|
|
if (!methods.includes(request.method)) {
|
|
return response.status(405).json("")
|
|
}
|
|
|
|
return handler(request, response)
|
|
}
|
|
}
|
|
```
|
|
|
|
To use this middleware, we call our API handler by wrapping it inside `withMethods`:
|
|
|
|
```ts
|
|
async function handler(request: NextApiRequest, response: NextApiResponse) {}
|
|
|
|
export default withMethods(["POST"], handler)
|
|
```
|
|
|
|
### withValidation
|
|
|
|
Next, we're going to create a middleware to validate `request.body`
|
|
|
|
```ts
|
|
import type { NextApiHandler, NextApiRequest, NextApiResponse } from "next"
|
|
import type { ObjectShape, OptionalObjectSchema } from "yup/lib/object"
|
|
|
|
export function withValidation<T extends OptionalObjectSchema<ObjectShape>>(
|
|
schema: T,
|
|
handler: NextApiHandler
|
|
) {
|
|
return async function (request: NextApiRequest, response: NextApiResponse) {
|
|
try {
|
|
request.body = await schema.validate(request.body)
|
|
|
|
return handler(request, response)
|
|
} catch (error) {
|
|
if (error instanceof yup.ValidationError) {
|
|
return response.status(422).json(error.message)
|
|
}
|
|
|
|
return response.status(422).json("")
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
This middleware accepts a schema to validate `request.body` against. We use it as follows:
|
|
|
|
```ts
|
|
const postSchema = yup.object({
|
|
title: yup.string().required("`Title` field missing."),
|
|
body: yup.string().required("`Body` field missing"),
|
|
})
|
|
|
|
interface Post extends yup.TypeOf<typeof postSchema> {}
|
|
|
|
async function handler(request: NextApiRequest, response: NextApiResponse) {
|
|
const post: Post = request.body
|
|
|
|
// TODO: Save post.
|
|
|
|
response.status(201).json("")
|
|
}
|
|
|
|
export default withValidation(postSchema, handler)
|
|
```
|
|
|
|
## Chaining
|
|
|
|
We can call mutiple middlewares by chaining:
|
|
|
|
```ts title="pages/api/posts"
|
|
export default withMethods(["POST"], withValidation(postSchema, handler))
|
|
```
|
|
|
|
## Code
|
|
|
|
You can check out the code here: [https://github.com/arshad/nextjs-middleware-validation](https://github.com/arshad/nextjs-middleware-validation).
|