87

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?

4 Answers 4

108

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.

Sign up to request clarification or add additional context in comments.

5 Comments

Instead of a generic 400 Bad Request error, it would be more appropriate to return 405 Method Not Allowed. developer.mozilla.org/en-US/docs/Web/HTTP/Status/405
Good call, updated the answer to use a 405 status code instead
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.
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. vercel.com/docs/concepts/limits/…
As long as from the Front, the Header is sent: Content-Type: application/json (for Next.js v12+).
30

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.

1 Comment

Note: If you make a request with fetch, remember to set Content-Type to application/json, otherwise Next.js will not parse automatically.
8

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

1 Comment

Don't forget await when calling res.json()
0

I had the same issue, later found out that a colleague had added

export const config = {
    api: {
        bodyParser: false,
    },
};

removing that from the file or changing bodyParser: true solve the problem.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.