docs: updated API Routes and Middlewares docs (#5588)

* docs: updated API Routes and Middlewares docs

* fix eslint errors
This commit is contained in:
Shahed Nasser
2023-11-10 12:00:08 +02:00
committed by GitHub
parent 3781ac4631
commit d4b8a89e66
2 changed files with 183 additions and 56 deletions

View File

@@ -115,7 +115,7 @@ For example, if your API route accepts an author ID and a post ID, the path to y
## CORS Configuration
CORS configurations are automatically added to custom API Routes defined under the `/store` or `/admin` path prefixes based on the [store_cors and admin_cors configurations](../backend/configurations.md#admin_cors-and-store_cors) respectively.
The `cors` middleware, which enables Cross-Origin Resource Sharing (CORS), is automatically applied on custom API Routes defined under the `/store` or `/admin` path prefixes based on the respective [store_cors and admin_cors configurations](../backend/configurations.md#admin_cors-and-store_cors).
To add CORS configurations to custom API routes under other path prefixes, or override the CORS configurations added by default, define a [middleware](./add-middleware.mdx) on your API routes and pass it the `cors` middleware. For example:
@@ -140,6 +140,30 @@ export const config: MiddlewaresConfig = {
}
```
### CORS Opt-Out
To disable the `cors` middleware for an API Route, export a `CORS` variable in the route file with its value set to `false`.
For example:
```ts title=src/api/store/custom/route.ts
import type {
MedusaRequest,
MedusaResponse,
} from "@medusajs/medusa"
export const GET = (
req: MedusaRequest,
res: MedusaResponse
) => {
res.json({
message: "[GET] Hello world!",
})
}
export const CORS = false
```
---
## Parse Request Body Parameters
@@ -192,6 +216,72 @@ export const config: MiddlewaresConfig = {
Note that the `urlencoded` middleware imported from the [body-parser package](https://www.npmjs.com/package/body-parser) attaches the parsed data to the `MedusaRequest` object's `body` property as well.
### Parse Webhook Body Parameters
For webhook API Routes, you may need to use the `raw` body parser middleware rather than the default `json`.
You can opt out of the default body parser by setting the `bodyParser` property of a [middleware route object](./add-middleware.mdx) to `false`, and passing the preferred body-parser middleware in the `middlewares` property.
For example:
```ts title=src/api/middlewares.ts
import { MiddlewaresConfig } from "@medusajs/medusa"
import { raw } from "body-parser"
export const config: MiddlewaresConfig = {
routes: [
{
matcher: "/webhooks/*",
bodyParser: false,
middlewares: [raw({ type: "application/json" })],
},
],
}
```
You can also disable the default `json` body parser for specific HTTP methods using the `method` property for a middleware route object. Its value can either be a string or an array of strings, each being an HTTP method name.
For example:
```ts title=src/api/middlewares.ts
import { MiddlewaresConfig } from "@medusajs/medusa"
import { raw } from "body-parser"
export const config: MiddlewaresConfig = {
routes: [
{
method: ["POST", "PUT"],
matcher: "/webhooks/*",
bodyParser: false,
middlewares: [raw({ type: "application/json" })],
},
],
}
```
This disables the default JSON body parser for the POST and PUT HTTP methods on API Routes matching the `/webhooks/*` matcher, and applies the `raw` body-parser middleware on them instead.
### Configure Request Body Size Limit
By default, the maximum request body size allowed is `1000` bytes. If a request body's size is greater than that, an error is thrown.
If you expect the request body of an API Route to be larger than the default, you can set the `bodyParser` property of a [middleware route object](./add-middleware.mdx) to a configuration object with the property `sizeLimit`. Its value is a number indicating the maximum allowed size limit in bytes.
For example:
```ts title=src/api/middlewares.ts
import { MiddlewaresConfig } from "@medusajs/medusa"
export const config: MiddlewaresConfig = {
routes: [
{
bodyParser: { sizeLimit: 2000 }, // in bytes
// ...
},
],
}
```
---
## Protected API Routes
@@ -390,63 +480,19 @@ export const GET = (
## Handle Errors
Medusa provides an `errorHandler` middleware that you can use on your custom API Routes so that your error handling is consistent with the Medusa backend. You can also create custom [middlewares](./add-middleware.mdx) to handle errors.
Medusa automatically applies an error-handler middleware on your custom API routes, which returns errors as a JSON response whose format is consistent with the Medusa backend.
To handle errors using Medusa's middlewares, first, import the `errorHandler` middleware from `@medusajs/medusa` and apply it on your routes.
:::tip
For example:
When an error is thrown, the response status code is set to `500` by default. However, that changes based on the `MedusaError` type thrown as explained in the next section.
```ts title=src/api/middlewares.ts
import {
errorHandler,
type MiddlewaresConfig,
} from "@medusajs/medusa"
:::
export const config: MiddlewaresConfig = {
routes: [
{
matcher: "/store/custom*",
middlewares: [errorHandler()],
},
],
}
```
### Medusa Error Types
Make sure it's applied after all other middlewares.
You must throw errors of type `MedusaError` to ensure the error message is returned in the response. Otherwise, the returned error message will be `Unknown Error`.
Then, wrap the method handler function of every API route method with the `wrapHandler` function imported from `@medusajs/medusa`. For example:
```ts title=src/api/store/custom/route.ts
import {
MedusaRequest,
MedusaResponse,
wrapHandler,
} from "@medusajs/medusa"
export const GET = wrapHandler(async (
req: MedusaRequest,
res: MedusaResponse
) => {
res.json({
message: "[GET] Hello world!",
})
})
export const POST = wrapHandler(async (
req: MedusaRequest,
res: MedusaResponse
) => {
res.json({
message: "[POST] Hello world!",
})
})
```
Now all errors thrown in your custom API Routes, or in resources you use within your API Route such as services, are caught and returned to the user.
### Using MedusaError
If you throw errors like this:
For example, if you throw an error like this:
```ts
throw new Error ("Post was not found")
@@ -462,7 +508,7 @@ The API Route returns the following object error in the response:
}
```
To ensure your error message is relayed in the response, it's recommended to use `MedusaError` imported from `@medusajs/utils` as the thrown error instead.
To ensure your error message is relayed in the response, use `MedusaError` imported from `@medusajs/utils` as the thrown error type instead.
For example:
@@ -492,6 +538,78 @@ After using `MedusaError`, the returned error in the response provides a clearer
}
```
<details>
<summary>
Available MedusaError Types and their respective status codes
</summary>
The default response code is `500` unless mentioned otherwise.
- `MedusaError.Types.DB_ERROR`: Sets the response code to `500`.
- `MedusaError.Types.DUPLICATE_ERROR`: Sets the response code to `422`.
- `MedusaError.Types.INVALID_ARGUMENT`
- `MedusaError.Types.INVALID_DATA`: Sets the resposne code to `400`.
- `MedusaError.Types.UNAUTHORIZED`: Sets the resposne code to `401`.
- `MedusaError.Types.NOT_FOUND`: Sets the response code to `404`.
- `MedusaError.Types.NOT_ALLOWED`: Sets the resposne code to `400`.
- `MedusaError.Types.UNEXPECTED_STATE`
- `MedusaError.Types.CONFLICT`: Sets the resposne code to `409`.
- `MedusaError.Types.PAYMENT_AUTHORIZATION_ERROR`: Sets the resposne code to `422`.
</details>
### Override Error Handler
To override the default error handler, pass the `errorHandler` property to the [exported middleware configurations](./add-middleware.mdx) with the custom error-handler middleware as its value.
For example:
```ts title=src/api/middlewares.ts
import { MiddlewaresConfig } from "@medusajs/medusa"
export const config: MiddlewaresConfig = {
errorHandler: (err, req, res, next) => {
// custom error handling logic...
},
}
```
### Disable Default Error Handler
To disable the default error handler, set the `errorHandler` property of the [exported middleware configurations](./add-middleware.mdx) to `false`.
For example:
```ts title=src/api/middlewares.ts
import { MiddlewaresConfig } from "@medusajs/medusa"
export const config: MiddlewaresConfig = {
errorHandler: false,
}
```
However, when you disable the default error handler, errors thrown in an `async` function or method are not handled and requests goes on indefinitely with no response.
To ensure that errors are still returned in the response when the default error handler is disabled, either create a custom error handler or wrap your API Route with the `wrapHandler` imported from `@medusajs/medusa`.
For example:
```ts title=src/api/middlewares.ts
import {
MedusaRequest,
MedusaResponse,
wrapHandler,
} from "@medusajs/medusa"
export const GET = wrapHandler(async (
req: MedusaRequest,
res: MedusaResponse
): Promise<void> => {
throw new Error("An error occured")
})
```
---
## Use Other Resources