2020-01-03 19:16:51 +01:00
---
description: API Routes provide built-in middlewares that parse the incoming request. Learn more about them here.
---
2019-12-23 16:07:38 +01:00
# API Middlewares
2020-05-02 06:06:23 +02:00
< details open >
< summary > < b > Examples< / b > < / summary >
< ul >
2020-05-27 23:51:11 +02:00
< li > < a href = "https://github.com/vercel/next.js/tree/canary/examples/api-routes-middleware" > API Routes with middleware< / a > < / li >
< li > < a href = "https://github.com/vercel/next.js/tree/canary/examples/api-routes-cors" > API Routes with CORS< / a > < / li >
2020-05-02 06:06:23 +02:00
< / ul >
< / details >
2019-12-23 16:07:38 +01:00
API routes provide built in middlewares which parse the incoming request (`req`). Those middlewares are:
- `req.cookies` - An object containing the cookies sent by the request. Defaults to `{}`
- `req.query` - An object containing the [query string ](https://en.wikipedia.org/wiki/Query_string ). Defaults to `{}`
- `req.body` - An object containing the body parsed by `content-type` , or `null` if no body was sent
## Custom config
Every API route can export a `config` object to change the default configs, which are the following:
```js
export const config = {
api: {
bodyParser: {
sizeLimit: '1mb',
},
},
}
```
The `api` object includes all configs available for API routes.
`bodyParser` Enables body parsing, you can disable it if you want to consume it as a `Stream` :
```js
export const config = {
api: {
bodyParser: false,
},
}
```
`bodyParser.sizeLimit` is the maximum size allowed for the parsed body, in any format supported by [bytes ](https://github.com/visionmedia/bytes.js ), like so:
```js
export const config = {
api: {
bodyParser: {
sizeLimit: '500kb',
},
},
}
```
2020-05-07 14:05:41 +02:00
`externalResolver` is an explicit flag that tells the server that this route is being handled by an external resolver like _express_ or _connect_ . Enabling this option disables warnings for unresolved requests.
```js
export const config = {
api: {
externalResolver: true,
},
}
```
2020-03-17 09:52:23 +01:00
## Connect/Express middleware support
2019-12-23 16:07:38 +01:00
2020-03-17 09:52:23 +01:00
You can also use [Connect ](https://github.com/senchalabs/connect ) compatible middleware.
2019-12-23 16:07:38 +01:00
2020-03-17 09:52:23 +01:00
For example, [configuring CORS ](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS ) for your API endpoint can be done leveraging the [cors ](https://www.npmjs.com/package/cors ) package.
2019-12-23 16:07:38 +01:00
2020-03-17 09:52:23 +01:00
First, install `cors` :
2019-12-23 16:07:38 +01:00
```bash
2020-03-17 09:52:23 +01:00
npm i cors
2019-12-23 16:07:38 +01:00
# or
2020-03-17 09:52:23 +01:00
yarn add cors
2019-12-23 16:07:38 +01:00
```
2020-03-17 09:52:23 +01:00
Now, let's add `cors` to the API route:
2019-12-23 16:07:38 +01:00
```js
2020-03-17 09:52:23 +01:00
import Cors from 'cors'
2019-12-23 16:07:38 +01:00
2020-03-17 09:52:23 +01:00
// Initializing the cors middleware
2019-12-23 16:07:38 +01:00
const cors = Cors({
2020-03-17 09:52:23 +01:00
methods: ['GET', 'HEAD'],
2019-12-23 16:07:38 +01:00
})
2020-03-17 09:52:23 +01:00
// Helper method to wait for a middleware to execute before continuing
// And to throw an error when an error happens in a middleware
function runMiddleware(req, res, fn) {
return new Promise((resolve, reject) => {
2020-05-18 21:24:37 +02:00
fn(req, res, (result) => {
2020-03-17 09:52:23 +01:00
if (result instanceof Error) {
return reject(result)
}
return resolve(result)
})
})
}
async function handler(req, res) {
// Run the middleware
await runMiddleware(req, res, cors)
// Rest of the API logic
2019-12-23 16:07:38 +01:00
res.json({ message: 'Hello Everyone!' })
}
2020-03-17 09:52:23 +01:00
export default handler
2019-12-23 16:07:38 +01:00
```
2020-05-02 06:06:23 +02:00
2020-05-27 23:51:11 +02:00
> Go to the [API Routes with CORS](https://github.com/vercel/next.js/tree/canary/examples/api-routes-cors) example to see the finished app
2020-07-16 07:03:48 +02:00
## Extending the `req`/`res` objects with TypeScript
For better type-safety, it is not recommended to extend the `req` and `res` objects. Instead, use pure functions to work with them:
```ts
// utils/cookies.ts
import { serialize } from 'cookie'
import { NextApiResponse } from 'next'
/**
* This sets `cookie` using the `res` object
*/
type Options = {
expires?: Date
maxAge?: number
}
export const setCookie = (
res: NextApiResponse,
name: string,
value: unknown,
options: Options = {}
) => {
const stringValue =
typeof value === 'object' ? 'j:' + JSON.stringify(value) : String(value)
if ('maxAge' in options) {
options.expires = new Date(Date.now() + options.maxAge)
options.maxAge /= 1000
}
res.setHeader('Set-Cookie', serialize(name, String(stringValue), options))
}
// pages/api/cookies.ts
import { NextApiRequest, NextApiResponse } from 'next'
import { setCookie } from '../../utils/cookies'
const handler = (req: NextApiRequest, res: NextApiResponse) => {
// Calling our pure function using the `res` object, it will add the `set-cookie` header
setCookie(res, 'Next.js', 'api-middleware!')
// Return the `set-cookie` header so we can display it in the browser and show that it works!
res.end(res.getHeader('Set-Cookie'))
}
export default handler
```
If you can't avoid these objects from being extended, you have to create your own type to include the extra properties:
```ts
// pages/api/foo.ts
import { NextApiRequest, NextApiResponse } from 'next'
import { withFoo } from 'external-lib-foo'
type NextApiRequestWithFoo = NextApiRequest & {
foo: (bar: string) => void
}
const handler = (req: NextApiRequestWithFoo, res: NextApiResponse) => {
req.foo('bar') // we can now use `req.foo` without type errors
res.end('ok')
}
export default withFoo(handler)
```
Keep in mind this is not safe since the code will still compile even if you remove `withFoo()` from the export.