Next.js: Next.js 9 API route works on Get Request but not Post request

Created on 14 Jul 2019  ·  23Comments  ·  Source: vercel/next.js

Question about Next.js

I try to modified some of the api to use post instead of get.
I have request code like this with normal fetch

 const response = await fetch(`${process.env.SERVER}/api/lyric?id=${song.song_id}`);

It will get to the file inside ./page/api and resolve, however, if I change to code to following

 const response = await fetch(`${process.env.SERVER}/api/lyric`, {
                    method: 'POST',
                    body: JSON.stringify({id: song.song_id})
                });

It will give me 404 not found. I wonder what is the problem here ?

Thank you

Most helpful comment

I also see the 404 in our project with the following:

const res = await fetch('/api/bookings', {
  method: 'POST',
  body: JSON.stringify({ hungry: true }),
  headers: {
    'Content-Type': 'application/json',
  },
})
const data = await res.json()

It dosent matter what the content is in the api/bookings file. It will never be hit. I'm using now dev to run the project on localhost

Update
I found out that it worked fine with the now dev but it did not work with my server.js file due to i had not handled post requests. If you simply add a handler for post request, everything will work fine:

server.post('*', (req, res) => {
  return handle(req, res)
})

All 23 comments

Hey @zluo01, provide full reproduction, from your issue it's hard to guess what could be wrong. You can check integration test for POST.

Were you able to figure this out? The documentation for API routes is pretty minimal, and I'm also receiving a 404 response for POST requests sent to a route that worked fine for GET requests

Were you able to figure this out? The documentation for API routes is pretty minimal, and I'm also receiving a 404 response for POST requests sent to a route that worked fine for GET requests

Sorry no, I use Get and put stuff inside headers instead and I do not have time to produce a full reproduction.

Some documentation on handling POST would be useful

@stoplion what would you like to have documented? Can you create an issue following the issue template for it?

Sure

I also see the 404 in our project with the following:

const res = await fetch('/api/bookings', {
  method: 'POST',
  body: JSON.stringify({ hungry: true }),
  headers: {
    'Content-Type': 'application/json',
  },
})
const data = await res.json()

It dosent matter what the content is in the api/bookings file. It will never be hit. I'm using now dev to run the project on localhost

Update
I found out that it worked fine with the now dev but it did not work with my server.js file due to i had not handled post requests. If you simply add a handler for post request, everything will work fine:

server.post('*', (req, res) => {
  return handle(req, res)
})

@TommySorensen this should be fixed in the latest canary

Was this ever answered? Is there a way to POST to a Next v9 API Route?

Was this ever answered? Is there a way to POST to a Next v9 API Route?

Yes. Just posting to the api routes will work just fine. Use this example and change the get to post. Thats what i did. Worked like a charm 😉

@huv1k any idea on a release?

@lifeiscontent release of what?

@huv1k on when the next release of next.js will come out with this fix

@lifeiscontent There is no bug to fix. I tested it my self. POST work just fine if you use of the NextJS examples. It's properly something in your application. Please provide example of the full code, so we can help with the investigation 👍

easy deasy
in your _custom server_
do

server.use((req, res) => app.getRequestHandler()(req, res))

Repro:

npx create-next-app --example with-firebase-authentication with-firebase-authentication-app

Add file api/test.js

export default (req, res) => {
  console.log('api test', req.method)
  res.json('ok')
}

Add request handler in server.js:

server.use((req, res) => app.getRequestHandler()(req, res))

Run yarn dev (or node server.js)

Send POST to http://localhost:3000/api/test

Expected: console logs api test POST
Actual: no logs, request stays pending until timeout

You need to update the example:

  server.get('*', (req, res) => {
    return handle(req, res)
  })

needs to be:

  server.all('*', (req, res) => {
    return handle(req, res)
  })

Found our mistake: upgrading isomorphic-unfetch => DO NOT UPGRADE 🤕

By the way, Firebase dependency is quite old:

 firebase             ^5.6.0  →    ^7.2.1
 firebase-admin       ^5.8.2  →    ^8.6.1

If anyone has this issue yet with a custom express server, it can occur while using multiple body parsers, because NextJs api routes enables it by default. Use only express body parser, or only NextJs body parser. How to disable NextJs body parser documented there: https://nextjs.org/docs#api-middlewares

@epranka @thgh, Man, it took me hours to figure this one out.

I'm using the Firebase Cloud Functions server, and I couldn't make any POST requests to my API route. POST requests would hang, but GET requests would work fine. And if I was using the local NextJS dev server, POST requests would also work fine.

Disabling the body parser when using Firebase Cloud Functions fixed it.

Apparently Firebase Cloud Functions comes with its own body parser, and it conflicts with the NextJS one. So you have to disable the body parser for Firebase Cloud Functions, but enable it for local development using the NextJS dev server.

So basically drop this in your pages/api/[yourEndPoint].js:

export const config = {
  api: {
    bodyParser: process.env.NODE_ENV !== 'production'
  }
};

@TommySorensen answer solved it for me:

  server.get("*", (req, res) => handle(req, res));
  server.post("*", (req, res) => handle(req, res));

Many thanks!

@epranka @thgh, Man, it took me hours to figure this one out.

I'm using the Firebase Cloud Functions server, and I couldn't make any POST requests to my API route. POST requests would hang, but GET requests would work fine. And if I was using the local NextJS dev server, POST requests would also work fine.

Disabling the body parser when using Firebase Cloud Functions fixed it.

Apparently Firebase Cloud Functions comes with its own body parser, and it conflicts with the NextJS one. So you have to disable the body parser for Firebase Cloud Functions, but enable it for local development using the NextJS dev server.

So basically drop this in your pages/api/[yourEndPoint].js:

export const config = {
  api: {
    bodyParser: process.env.NODE_ENV !== 'production'
  }
};

Thanks! Was facing the exact same issue. Resolved with your fix. Its surprising that Firebase functions do not give any config to turn off automatic body parsing.

so we have to use custom server, got it but getting the parsed body inside api route would have solved many problems.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

renatorib picture renatorib  ·  3Comments

swrdfish picture swrdfish  ·  3Comments

havefive picture havefive  ·  3Comments

knipferrc picture knipferrc  ·  3Comments

flybayer picture flybayer  ·  3Comments