Access raw body of Stripe webhook in Nest.js

For anyone looking for a more elegant solution, turn off the bodyParser in main.ts. Create two middleware functions, one for rawbody and the other for json-parsed-body.

json-body.middleware.ts

import { Request, Response } from 'express';
import * as bodyParser from 'body-parser';
import { Injectable, NestMiddleware } from '@nestjs/common';

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

raw-body.middleware.ts

import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response } from 'express';
import * as bodyParser from 'body-parser';

@Injectable()
export class RawBodyMiddleware implements NestMiddleware {
    use(req: Request, res: Response, next: () => any) {
        bodyParser.raw({type: '*/*'})(req, res, next);
    }
}

Apply the middleware functions to appropriate routes in app.module.ts.

app.module.ts

[...]

export class AppModule implements NestModule {
    public configure(consumer: MiddlewareConsumer): void {
        consumer
            .apply(RawBodyMiddleware)
            .forRoutes({
                path: '/stripe-webhooks',
                method: RequestMethod.POST,
            })
            .apply(JsonBodyMiddleware)
            .forRoutes('*');
    }
}

[...]

And tweak initialization of Nest to turn off bodyParser:

main.ts

[...]

const app = await NestFactory.create(AppModule, { bodyParser: false })

[...]

BTW req.rawbody has been removed from express long ago.

https://github.com/expressjs/express/issues/897

Leave a Comment