16

I was trying to send a post request to my api. However trying to access the request body in the route handler causes the error below:

Code:

export async function POST(request: Request) {
  const postBody: postProps = JSON.parse(request.body) //  Error here on request.body
  ...
}

Error: Argument of type 'ReadableStream' is not assignable to parameter of type 'string'.

Any help would be appreciated

lool
  • 345
  • 1
  • 6
  • 11

2 Answers2

36

You need to call json() on the Request object.

export async function POST(request: Request) {
  const res = await request.json() // res now contains body
}
Michael
  • 6,561
  • 5
  • 38
  • 55
  • Thanks, this worked. So does request automatically contain body now in next 13.2 since i was used to req.body before? – lool Mar 08 '23 at 07:06
  • 3
    What happens if you aren't receiving `application/json`? For me it errors out on Json parse – Andrew K May 19 '23 at 17:42
  • 2
    One question: if your type was not ````Request```` but ````NextApiRequest````, how would you then extract the body ? Thanks – BlackLabrador Jun 06 '23 at 09:52
  • @BlackLabrador `NextApiRequest` should only be used for the `/pages` directory. This question is for the `/app` directory. In that case, however, you'll use `JSON.parse(request.body)`, as shown in the question. – andrilla Jun 17 '23 at 12:10
  • @AndrewK did you found an answer how to handle a case where you're not receiving an `application/json` body. For me it also errors out. – BenjaminK Jul 03 '23 at 09:42
  • I have a serious question, Why they don't write such things in the documentation? I mean how do you expect people to work on POST request without accessing request.body? – Ryan Dhungel Jul 12 '23 at 04:45
4

I was having issues Verifying the webhook from Clerk in Next.js using App Router.

The following worked for me.

import { Webhook } from "svix";

export async function POST(req: NextRequest) {
  const svix_id = req.headers.get("svix-id") ?? '';
  const svix_timestamp = req.headers.get("svix-timestamp") ?? '';
  const svix_signature = req.headers.get("svix-signature") ?? '';
  
  const body = await req.text(); // This get's the raw body as a string
  
  const sivx =  new Webhook("your_secret_key_here")

  const payload = sivx.verify(body, {
    "svix-id": svix_id,
    "svix-timestamp": svix_timestamp,
    "svix-signature": svix_signature,

  });

  // The payload is the json.
  console.log(payload);

  // The rest of your code

  return NextResponse.json(null, { status: 200 })

}


For reference:

https://developer.mozilla.org/en-US/docs/Web/API/Response/text

Kyle Davis
  • 51
  • 5