How to parse the raw body of a request in a NestJS controller
Tags: javascript, nestjs, webdev
Published: 2021-06-20 03:57:25

---
title: How to parse the raw body of a request in a NestJS controller
published: true
date: 20/06/2021
tags: #javascript #nestjs #webdev
canonical_url: https://darraghoriordan.com/2021/06/20/parse-request-raw-body-nest-js-controller/
---

I recently needed to parse the raw body in a NestJS application to validate a webhook from a third party service. The key to this was using the json validate method to read the raw body in to a variable before passing the request on to the next middleware.

<!-- end excerpt -->
## Why would you need raw body?

If you accept any webhooks from third party services you might need to parse the request and verify it with a hash. You can’t modify the request in any way or the hashes will not match the expected value. You must use the request stream as it is sent.

Nest js automatically parses your application requests into JSON. This is perfect for 99% of use cases with NestJS web applications. We have to bypass this functionality.

## The steps

1. Turn off NestJS automatic body parsing
2. Add required middleware classes
3. Wire up the middleware in NestJS bootstrapping

## Turn off NestJS automatic body parsing

Somewhere in your application you will bootstrap your application

```
async function bootstrap() {
  const app = await NestFactory.create(AppModule)
  await app.listen(3000)
}

bootstrap()
```

You need to pass the option to create method that disables body parsing

```
async function bootstrap() {
  const app = await NestFactory.create(AppModule, { bodyParser: false })
  await app.listen(3000)
}

bootstrap()
```

## Add the required middleware classes

Add a `RawBodyMiddleware.ts`

```
import { Injectable, NestMiddleware } from '@nestjs/common'
import { json } from 'body-parser'

/**
 * Copied this middleware to parse the raw response into a param to use later
 * from https://github.com/golevelup/nestjs/blob/master/packages/webhooks/src/webhooks.middleware.ts
 */
@Injectable()
export class RawBodyMiddleware implements NestMiddleware {
  public constructor() {}

  public use(req: Request, res: Response<any>, next: () => any): any {
    json({
      verify: (req: any, res, buffer) => {
        if (Buffer.isBuffer(buffer)) {
          const rawBody = Buffer.from(buffer)
          req['parsedRawBody'] = rawBody
        }
        return true
      },
    })(req, res as any, next)
  }
}
```

Add a `JsonBodyMiddleware`

```
import { Injectable, NestMiddleware } from '@nestjs/common'
import { json } from 'body-parser'

@Injectable()
export class JsonBodyMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: () => any) {
    json()(req as any, res as any, next)
  }
}
```

## Wire up the middleware into the NestJs Bootstrapping

We need to tell NestJS to parse the specified routes with the raw body parser. Then parse every other route with the regular JSON parser.

Then you can add any middleware you like after that.

```
// This is an array of routes we want raw body parsing to be available on
const rawBodyParsingRoutes: Array<RouteInfo> = [
  {
    path: '*my/rawbody/required/route*',
    method: RequestMethod.POST,
  },
]

export class AppModule implements NestModule {
  public configure(consumer: MiddlewareConsumer): MiddlewareConsumer | void {
    consumer
      .apply(RawBodyMiddleware)
      .forRoutes(...rawBodyParsingRoutes)
      .apply(JsonBodyMiddleware)
      .exclude(...rawBodyParsingRoutes)
      .forRoutes('*')
      .apply(MyOtherMiddleware)
      .forRoutes({ path: '*', method: RequestMethod.ALL })
  }
}
```

## Access the raw body in a NestJS controller

Now in the controller for handling the specified route we can access the `parsedRawBody` parameter.

```
const payload = request.parsedRawBody?.toString()
```

Tip: If you don’t see a body here make sure that the path you specified is actually triggering the raw body parser.