Using multipart/form-data in Nestjs

Solution 1:

I had a similar task, receiving a .csv file and sending it to another server.

controller:

    @UseInterceptors(FileInterceptor('file'))
    @Post('upload')
    async uploadFile(@UploadedFile() file: Express.Multer.File) {
      
      await this.myService.uploadFile(file);
      return {
        message: 'File uploaded successfully.',
      };
    }

service:

    import * as FormData from 'form-data';
    import { Readable } from 'stream';
    
    async uploadFile(file: Express.Multer.File) {
    const form = new FormData();

    form.append('files', Readable.from(file.buffer), {
      filename: file.originalname,
    });

    try {
      const result = await lastValueFrom(
        this.httpService.post('The URL of your third-party service', form, {
          headers: {
            ...form.getHeaders(),
          },
        }),
      );

      if (result.status === 200) return;
    } catch {
      
      throw new InternalServerErrorException(
        'Error while uploading the .csv file.',
      );
    }
    }

Some explanations here:

  • It requires importing Formdata from the package.
  • .append() requires a fieldName, and a readable Stream.
  • You can use the buffer of the file that's on memory (not recommended with large files) and use it to create a readable stream.
  • Also, you need to add the name of the file manually since Formdata only recognizes the filename if the file is saved on disk. (Which in our case is on memory as a Buffer).
  • You can create the stream in different ways, the example is not mandatory.
  • .getHeaders() will generate the default header 'Content-Type': 'multipart/form-data' and also it will generate the boundary of the file, like this: reference
      {
        'content-type': 'multipart/form-data; boundary=--------------------------286308325485491440714225'
      }