Skip to content Skip to sidebar Skip to footer

How Do I Pass Plain Text As My Request Body Using Nestjs?

One of the controller methods in my NestJS application is supposed to take plain text as its body but whenever I try to make a request, the parameter is received as an empty object

Solution 1:

I see that this question is pretty old, but it is listed in google among first, so I want to add answer here.

If you don't want to add body-parser middleware (for example, you want plain text only in single controller method), you can use raw-body (which is already exists in your node_modules), something like this:

import * as rawbody from'raw-body';
import { Controller, Post, Body, Req } from'@nestjs/common';

@Controller('/')
exportclassIndexController {

  @Post()
  asyncindex(@Body() data, @Req() req) {

    // we have to check req.readable because of raw-body issue #57// https://github.com/stream-utils/raw-body/issues/57if (req.readable) {
      // body is ignored by NestJS -> get raw body from requestconst raw = awaitrawbody(req);
      const text = raw.toString().trim();
      console.log('body:', text);

    } else {
      // body is parsed by NestJSconsole.log('data:', data);
    }

    // ...
  }

}

you could also create new parameter decorator

import * as rawbody from'raw-body';
import { createParamDecorator, HttpException, HttpStatus } from'@nestjs/common';

exportconstPlainBody = createParamDecorator(async (data, req) => {
  if (req.readable) {
    return (awaitrawbody(req)).toString().trim();
  }
  thrownewHttpException('Body aint text/plain', HttpStatus.INTERNAL_SERVER_ERROR);
});

and use it like

@Post()
asyncindex(@PlainBody() text: string) {
  // ...

(I didn't check decorator code, wrote it right here in comment)

Solution 2:

Adding on @yumaa's post above

Here's the working decorator with NestJS v7.0.8:

import { createParamDecorator, ExecutionContext, BadRequestException } from'@nestjs/common';
import * as rawBody from"raw-body";

exportconstPlainBody = createParamDecorator(async (_, context: ExecutionContext) => {
    const req = context.switchToHttp().getRequest<import("express").Request>();
    if (!req.readable) { thrownewBadRequestException("Invalid body"); }

    const body = (awaitrawBody(req)).toString("utf8").trim();
    return body;
})

Solution 3:

The semantics of a post request are determined by the header that indicates the content type. Try making sure the request header has the type 'text/plain' and see of this helps.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST

Solution 4:

Nest is not compatible with plain/text and you must pass a bodyparser to your express app instead. Try something like this:

import * as bodyParser from'body-parser';


asyncfunctionbootstrap() {
  const app = awaitNestFactory.create(AppModule);
  app.use(bodyparser({ ...options })) // for plain/text bodiesawait app.listen(3000)
}
bootstrap();

where options is created from https://www.npmjs.com/package/body-parser

Solution 5:

Old question but none of the above worked for me but the following did:

The above decorator or controller-method approaches did not work for me as the request body buffer had always already been read.

I was able to get it working using the following middleware. (Note in my case I needed to validate a Xero webhook so the example is geared towards that)

cache-raw-body-on-request.ts:

import { json } from'body-parser';
import * as cloneBuffer from'clone-buffer';

exportconst cachedRawBodyRequestKey = 'rawBodyBuffer';

/**
 * Clones the request buffer and stores it on the request object for reading later 
 */exportconst cacheRawBodyOnRequest = json({
  verify: (req: any, res, buf, encoding) => {

    // only clone the buffer if we're receiving a Xero webhook requestif (req.headers['x-xero-signature'] && Buffer.isBuffer(buf)) {
      req[cachedRawBodyRequestKey] = cloneBuffer(buf);
    }
    returntrue;
  },
});

main.ts:

app.use(cacheRawBodyOnRequest);

controller:

const textBody = req[cachedRawBodyRequestKey].toString('utf-8');

Post a Comment for "How Do I Pass Plain Text As My Request Body Using Nestjs?"