Last active
October 17, 2023 23:11
-
-
Save jonilsonds9/efc228e34a298fa461d378f48ef67836 to your computer and use it in GitHub Desktop.
Uploading binary file (buffer) using NestJS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Had to upload a binary file but multer only works with `multipart/form-data` | |
| // And NestJS parses the request. So I had to manually upload it. | |
| // First in `main.ts` I had to edit the following line: | |
| const app = await NestFactory.create(AppModule); | |
| // For: | |
| const app = await NestFactory.create(AppModule, { bodyParser: false }); | |
| // So NestJS allows us to handle the request. | |
| // The next step is to create a Middleware, I named it `FileBufferMiddleware` | |
| // I added the following content: | |
| import { Injectable, NestMiddleware } from '@nestjs/common'; | |
| import { raw } from 'body-parser'; | |
| @Injectable() | |
| export class FileBufferMiddleware implements NestMiddleware { | |
| use(req: any, res: any, next: () => void): any { | |
| raw({ | |
| verify: (req, res, buffer) => { | |
| req['fileBuffer'] = buffer; | |
| }, | |
| limit: '5mb', | |
| })(req, res as any, next); | |
| } | |
| } | |
| // We need to add to our `MiddlewareModule` like so: | |
| export class MiddlewareModule implements NestModule { | |
| configure(consumer: MiddlewareConsumer) { | |
| consumer | |
| .apply(FileBufferMiddleware) | |
| .forRoutes({ | |
| path: '/upload/:fileName', | |
| method: RequestMethod.PUT, | |
| }); | |
| } | |
| } | |
| // With that we will have a `fileBuffer` which is a Buffer object in the request. | |
| // And to make it even easier, I also created a decorator named `FileBuffer`: | |
| import { createParamDecorator, ExecutionContext } from '@nestjs/common'; | |
| export const FileBuffer = createParamDecorator( | |
| (data: unknown, ctx: ExecutionContext) => { | |
| const request = ctx.switchToHttp().getRequest(); | |
| return request.fileBuffer || null; | |
| }, | |
| ); | |
| // So, we can just use the decorator in the Controller and we will already have the object ready to manipulate: | |
| @Put('/upload/:fileName') | |
| upload( | |
| @Res() response: Response, | |
| @Param() fileName: string, | |
| @FileBuffer() fileBuffer, | |
| ): object { | |
| if (fileBuffer === null) throw new BadRequestException('File is required'); | |
| const writeStream = createWriteStream(`./data/${fileName}`); | |
| writeStream.write(fileBuffer); | |
| return response | |
| .status(HttpStatus.CREATED) | |
| .send({ HttpCode: 201, Message: 'File uploaded.' }); | |
| } | |
| // And that's it, now we have an upload using a binary file. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for this.
One thing to note: for me I kept on getting the
BadRequestExceptionuntil I added the following line to therawfunctions options:type: image/jpeg