1d54e8fdc1
- Add new documentation pages for API route intro, responses, errors, and validation - General fixes and improvements across existing API route guides > Note: I didn't work on the guide for additional data validation. Will work on this as part of my next focus on workflows.
136 lines
4.2 KiB
Plaintext
136 lines
4.2 KiB
Plaintext
export const metadata = {
|
|
title: `${pageNumber} Request Body Parameter Validation`,
|
|
}
|
|
|
|
# {metadata.title}
|
|
|
|
In this chapter, you'll learn how to validate request body parameters in your custom API route.
|
|
|
|
## Example Scenario
|
|
|
|
Consider you're creating a `POST` API route at `/store/custom`. It accepts two paramters `a` and `b` that are required numbers, and returns their sum.
|
|
|
|
The next steps explain how to add validation to this API route, as an example.
|
|
|
|
---
|
|
|
|
## Step 1: Create Zod Schema
|
|
|
|
Medusa uses [Zod](https://zod.dev/) to validate the body parameters of an incoming request.
|
|
|
|
To use Zod to validate your custom schemas, create a `validators.ts` file in any `src/api` subfolder. This file holds Zod schemas for each of your API routes.
|
|
|
|
For example, create the file `src/api/store/custom/validators.ts` with the following content:
|
|
|
|
```ts title="src/api/store/custom/validators.ts"
|
|
import { z } from "zod"
|
|
|
|
export const PostStoreCustomSchema = z.object({
|
|
a: z.number(),
|
|
b: z.number()
|
|
})
|
|
```
|
|
|
|
The `PostStoreCustomSchema` variable is a Zod schema that indicates the request body is valid if:
|
|
|
|
1. It's an object.
|
|
2. It has a property `a` that is a required number.
|
|
3. It has a property `b` that is a required number.
|
|
|
|
---
|
|
|
|
## Step 2: Add Validation Middleware
|
|
|
|
To use this schema for validating the body parameters of requests to `/store/custom`, use the `validateAndTransformBody` middleware provided by `@medusajs/medusa`. It accepts the Zod schema as a parameter.
|
|
|
|
For example, create the file `src/api/middlewares.ts` with the following content:
|
|
|
|
```ts title="src/api/middlewares.ts"
|
|
import { defineMiddlewares } from "@medusajs/medusa"
|
|
import {
|
|
validateAndTransformBody
|
|
} from "@medusajs/medusa/dist/api/utils/validate-body"
|
|
import { PostStoreCustomSchema } from "./store/custom/validators"
|
|
|
|
export default defineMiddlewares({
|
|
routes: [
|
|
{
|
|
matcher: "/store/custom",
|
|
method: "POST",
|
|
middlewares: [
|
|
validateAndTransformBody(PostStoreCustomSchema)
|
|
],
|
|
},
|
|
],
|
|
})
|
|
```
|
|
|
|
This applies the `validateAndTransformBody` middleware on `POST` requests to `/store/custom`. It uses the `PostStoreCustomSchema` as the validation schema.
|
|
|
|
### How the Validation Works
|
|
|
|
If a request's body parameters don't pass the validation, the `validateAndTransformBody` middleware throws an error indicating the validation errors.
|
|
|
|
If a request's body parameters are validated successfully, the middleware sets the validated body parameters in the `validatedBody` property of `MedusaRequest`.
|
|
|
|
---
|
|
|
|
## Step 3: Use Validated Body in API Route
|
|
|
|
In your API route, consume the validated body using the `validatedBody` property of `MedusaRequest`.
|
|
|
|
For example, create the file `src/api/store/custom/route.ts` with the following content:
|
|
|
|
export const routeHighlights = [
|
|
["5", "PostStoreCustomSchemaType", "Infer the request body type from the schema to pass it as a type parameter to `MedusaRequest`."],
|
|
["14", "", "Access the body parameters using `validatedBody`."]
|
|
]
|
|
|
|
```ts title="src/api/store/custom/route.ts" highlights={routeHighlights}
|
|
import { MedusaRequest, MedusaResponse } from "@medusajs/medusa";
|
|
import { z } from "zod"
|
|
import { PostStoreCustomSchema } from "./validators";
|
|
|
|
type PostStoreCustomSchemaType = z.infer<
|
|
typeof PostStoreCustomSchema
|
|
>
|
|
|
|
export const POST = async (
|
|
req: MedusaRequest<PostStoreCustomSchemaType>,
|
|
res: MedusaResponse
|
|
) => {
|
|
res.json({
|
|
sum: req.validatedBody.a + req.validatedBody.b
|
|
})
|
|
}
|
|
```
|
|
|
|
In the API route, you use the `validatedBody` property of `MedusaRequest` to access the values of the `a` and `b` properties.
|
|
|
|
<Note title="Tip">
|
|
|
|
To pass the request body's type as a type parameter to `MedusaRequest`, use Zod's `infer` type that accepts the type of a schema as a parameter.
|
|
|
|
</Note>
|
|
|
|
---
|
|
|
|
## Test it Out
|
|
|
|
To test out the validation, send a `POST` request to `/store/custom`. You can try sending incorrect request body parameters.
|
|
|
|
For example, if you omit the `a` parameter, you'll receive a `400` response code with the following response data:
|
|
|
|
```json
|
|
{
|
|
"type": "invalid_data",
|
|
"message": "Invalid request: Field 'a' is required"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Learn More About Validation Schemas
|
|
|
|
To see different examples and learn more about creating a validation schema, refer to [Zod's documentation](https://zod.dev).
|