API Routes Request Helpers

Examples

API Routes provide built-in request helpers which parse the incoming request (req):

  • req.cookies - An object containing the cookies sent by the request. Defaults to {}
  • req.query - An object containing the 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 configuration, which is the following:

  1. export const config = {
  2. api: {
  3. bodyParser: {
  4. sizeLimit: '1mb',
  5. },
  6. },
  7. }

The api object includes all config options available for API Routes.

bodyParser is automatically enabled. If you want to consume the body as a Stream or with raw-body, you can set this to false.

One use case for disabling the automatic bodyParsing is to allow you to verify the raw body of a webhook request, for example from GitHub.

  1. export const config = {
  2. api: {
  3. bodyParser: false,
  4. },
  5. }

bodyParser.sizeLimit is the maximum size allowed for the parsed body, in any format supported by bytes, like so:

  1. export const config = {
  2. api: {
  3. bodyParser: {
  4. sizeLimit: '500kb',
  5. },
  6. },
  7. }

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.

  1. export const config = {
  2. api: {
  3. externalResolver: true,
  4. },
  5. }

responseLimit is automatically enabled, warning when an API Routes’ response body is over 4MB.

If you are not using Next.js in a serverless environment, and understand the performance implications of not using a CDN or dedicated media host, you can set this limit to false.

  1. export const config = {
  2. api: {
  3. responseLimit: false,
  4. },
  5. }

responseLimit can also take the number of bytes or any string format supported by bytes, for example 1000, '500kb' or '3mb'. This value will be the maximum response size before a warning is displayed. Default is 4MB. (see above)

  1. export const config = {
  2. api: {
  3. responseLimit: '8mb',
  4. },
  5. }

Extending the req/res objects with TypeScript

For better type-safety, it is not recommended to extend the req and res objects. Instead, use functions to work with them:

  1. // utils/cookies.ts
  2. import { serialize, CookieSerializeOptions } from 'cookie'
  3. import { NextApiResponse } from 'next'
  4. /**
  5. * This sets `cookie` using the `res` object
  6. */
  7. export const setCookie = (
  8. res: NextApiResponse,
  9. name: string,
  10. value: unknown,
  11. options: CookieSerializeOptions = {}
  12. ) => {
  13. const stringValue =
  14. typeof value === 'object' ? 'j:' + JSON.stringify(value) : String(value)
  15. if (typeof options.maxAge === 'number') {
  16. options.expires = new Date(Date.now() + options.maxAge * 1000)
  17. }
  18. res.setHeader('Set-Cookie', serialize(name, stringValue, options))
  19. }
  20. // pages/api/cookies.ts
  21. import { NextApiRequest, NextApiResponse } from 'next'
  22. import { setCookie } from '../../utils/cookies'
  23. const handler = (req: NextApiRequest, res: NextApiResponse) => {
  24. // Calling our pure function using the `res` object, it will add the `set-cookie` header
  25. setCookie(res, 'Next.js', 'api-middleware!')
  26. // Return the `set-cookie` header so we can display it in the browser and show that it works!
  27. res.end(res.getHeader('Set-Cookie'))
  28. }
  29. 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:

  1. // pages/api/foo.ts
  2. import { NextApiRequest, NextApiResponse } from 'next'
  3. import { withFoo } from 'external-lib-foo'
  4. type NextApiRequestWithFoo = NextApiRequest & {
  5. foo: (bar: string) => void
  6. }
  7. const handler = (req: NextApiRequestWithFoo, res: NextApiResponse) => {
  8. req.foo('bar') // we can now use `req.foo` without type errors
  9. res.end('ok')
  10. }
  11. 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.