Tip - Extract body from multipart formdata

Allow for a request containing both files and data.

If there is intention to, in the same request of type multipart formdata, send both files and data, that is possible to be done. To achieve it, we can create an Interceptor. They are inspired by the Aspect Oriented Programming, and possess interesting capabilities. For instance, one could be used to obtain the text from a field in a request of type multipart formdata, then convert it to JSON and finally set its value to the body.

nest g itc files/interceptors/body
@Injectable()
export class BodyInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler) {
    const request = context.switchToHttp().getRequest<Request>();

    try {
      const body = JSON.parse(request.body.body);
      request.body = body;
    } catch (error) {
      if (error instanceof SyntaxError) {
        throw new BadRequestException(error.message);
      }
      throw error;
    }

    return next.handle();
  }
}

Note the following:

  • By putting the JSON.parse() call inside a try/catch statement this way, we can ensure that, in case of invalid syntax, the thrown exception will be similar to Nest.

  • We are expecting a SyntaxError, so we check if the error is an instanceof it (Thanks to Matt Pocock for his insight in this lesson). This also types the error accordingly. If it isn't, throw the error once again.

Then, the BodyInterceptor can be used after the FileInterceptor.

@UseInterceptors(FileInterceptor('file'), BodyInterceptor)

With this, the extraction of the @Body() and DTO-validation will work properly.

Commit - Interceptor to extract body from multipart formdata

Last updated