72

I want to setup a POST route in my api folder using next.js, And I'm sending the data to the route but I can't parse the data to actually save it in the database. what is the best way to handle POST routes in next.js. particularly parsing the data in JSON format?

juliomalves
  • 42,130
  • 20
  • 150
  • 146
Dastan
  • 1,929
  • 2
  • 10
  • 21

3 Answers3

99

To get POST requests working in Next.js API routes, you likely want to do 3 things.

  • Limit the method to POST
  • Use JSON.parse() to parse the JSON on in the route (not needed in NextJS v12+)
  • Send a request to the backend

https://nextjs.org/docs/api-routes/api-middlewares

API Route

API routes in Next.js by default support all types of requests, including GET, POST, DELETE, etc. So while it isn't required, it's a good idea to restrict the route to the methods you want to support.

In your case, if you want to only support POST requests on a certain route, you use req.method to filter out non-post requests.

if (req.method !== 'POST') {
  res.status(405).send({ message: 'Only POST requests allowed' })
  return
}

To parse the JSON, all you can use JSON.parse(). This is not needed if you're using NextJS v12+, as long as you've not set bodyParser: false.

const body = JSON.parse(req.body)

Put it all together, and your API route should look something like this:

// pages/route-name.js

export default function handler(req, res) {
  if (req.method !== 'POST') {
    res.status(405).send({ message: 'Only POST requests allowed' })
    return
  }


  // not needed in NextJS v12+
  const body = JSON.parse(req.body)

  // the rest of your code
}

Send the request

Lastly, you need to send a POST request from your front-end code to the backend. You may already know how to do this, but mentioning this for completeness.

fetch('/api/route-name', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(objectWithData),
})

Quick aside, you don't need to worry about cross-browser compatibility for fetch with Next.js. Next.js automatically adds a polyfill when needed.

Nick
  • 5,108
  • 2
  • 25
  • 58
  • 13
    Instead of a generic `400 Bad Request` error, it would be more appropriate to return `405 Method Not Allowed`. https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405 – aalaap Aug 29 '21 at 11:49
  • 2
    Good call, updated the answer to use a 405 status code instead – Nick Aug 29 '21 at 17:24
  • Is it possible to do it without using APIs from NextJS? My NextJS app is hosted on vercel and all my APIs are external. I want to avoid NextJS server-side APIs to avoid limitations on function execution in the vercel. I was hoping a post request to page route itself like `/cars` but `POST /cars` and NextJS uses its SSR thing to render page which uses `getServerSideProps(...)` where I write my logic to fetch data from external API. – shashwat Oct 17 '21 at 03:01
  • You don't need to worry about any function limitations with Next.js on Vercel. When deployed on Vercel, Next.js sites are combined into a single serverless function (or as few as possible if it doesn't fit into just one). All pages and API routes are served through that one serverless function. Sending a `Post` request to an API route is equivalent to sending one to a page in respect to Vercel's limits. https://vercel.com/docs/concepts/limits/overview#serverless-functions-created-per-deployment – Nick Oct 17 '21 at 03:24
  • As long as from the Front, the Header is sent: `Content-Type: application/json` (for Next.js v12+). – 1antares1 Oct 05 '22 at 18:11
27

As with everything, it depends. In Next.js v12, you do not need JSON.parse(req.body) in the API route as long as you have NOT explicitly set bodyParser: false in the exported configuration for the API route (see https://nextjs.org/docs/api-routes/api-middlewares). The req.body will be parsed automatically to an object for example if the content-type of the request is application/json. In this case since the content is pre-parsed into a object, trying to run JSON.parse(req.body) in the API will likely throw an error.

w. Patrick Gale
  • 1,643
  • 13
  • 22
  • 1
    **Note**: If you make a request with `fetch`, remember to set `Content-Type` to `application/json`, otherwise Next.js will **not** parse automatically. – Sandro Maglione Apr 26 '23 at 18:38
2

In Nextjs 13.4 you can use Route Handler

import { NextResponse } from 'next/server'
 
export async function POST() {
  const res = await fetch('https://data.mongodb-api.com/...', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'API-Key': process.env.DATA_API_KEY,
    },
    body: JSON.stringify({ time: new Date().toISOString() }),
  })
 
  const data = await res.json()
 
  return NextResponse.json(data)
}

For latest and readymade templates of route handlers and much more use Next.js 13+ Power Snippets | TypeScript/Javascript

krishnaacharyaa
  • 14,953
  • 4
  • 49
  • 88