How to handle file uploads in NestJs with Multer

How to handle file uploads in NestJs with Multer
Uploading file feature is required for all applications. We are going to explore how to set up a file upload feature using Multer in NestJs.

In this guide we’ll walk through how to use the Multer module from npm in NestJs application. Ensure that your application can easily manage user uploads. Also your can configure your application to handle files securely seamlessly.

Prerequisites

This is a hands-on guide. To follow along, you must have the following things:

  • Node.js (V14 or above)
  • Node Package Manager (npm)
  • Basic understanding of Node.js and NestJs
  • A code editor, like VS Code
  • NestJS CLI. You can use the npm install -g @nestjs/cli command to install the CLI.

How to Setup the Project

Create a new NestJs project using following:

				
					$ nest new file-upload-example
				
			

After creating new project navigate to the project directory using the following command.

				
					$ cd file-upload-example
				
			

Next step we need to install an NPM module called multer. This is a middleware which help you manage the file uploads.

				
					$ npm install @nestjs/platform-express multer
				
			

And finally, install the @types/express and @types/multer packages:

				
					$ npm install -save-dev @types/express @types/multer
				
			

Now our project is ready with all required dependencies. Let dive into how to implement the files upload feature to this project.

How to Create a Resource for File Upload

With the NestJs CLI we can create the resources for handling the file uploads.

				
					$ nest generate resource file-upload
				
			

After running this command, a file-upload resource will automatically be created in your src folder: module, controller and service, to manage file uploads.

file-upload.module.ts organises the file upload logic, file-upload.controller.ts handles incoming file upload requests, and file-upload.service.ts handles the file upload operations. With the resource created, let’s configure the module, service and controller.

How to Configure the File Upload Resources

In this section we will understand and configure the following files in file-uploads:

  • file-upload.module.ts
  • file-upload.controller.ts
  • file-upload.service.ts

Module Configuration

				
					import { Module } from '@nestjs/common';
import { FileUploadService } from './file-upload.service';
import { FileUploadController } from './file-upload.controller';
import { MulterModule } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
@Module({
  imports: [
    MulterModule.register({
      storage: diskStorage({
        destination: './uploads',
        filename: (req, file, cb) => {
          const filename = `${Date.now()}-${file.originalname}`;
          cb(null, filename);
        },
      }),
    }),
  ],
  controllers: [FileUploadController],
  providers: [FileUploadService],
})
export class FileUploadModule {}

				
			

The above code is in the file-upload.module.ts where we specify where to save the files and how it should name the file.

Controller configuration

				
					import {
  Controller,
  Post,
  UseInterceptors,
  UploadedFile,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { FileUploadService } from './file-upload.service';

@Controller('file-upload')
export class FileUploadController {
  constructor(private readonly fileUploadService: FileUploadService) {}

  @Post('upload')
  @UseInterceptors(FileInterceptor('file'))
  uploadFile(@UploadedFile() file: Express.Multer.File) {
    return this.fileUploadService.handleFileUpload(file);
  }
}

				
			

This is the file-upload.controller.ts above. In this code there is a POST route created for handling the file uploads. This route will listen for file uploads and pass the file to the service for processing.

Service configuration

				
					import { Injectable } from '@nestjs/common';

@Injectable()
export class FileUploadService {
  handleFileUpload(file: Express.Multer.File) {
    return { message: 'File uploaded successfully', filePath: file.path };
  }
}
				
			

Here the service processes the file and returns a response with the file path.

Now the Module, Service and Controller is ready. As a next step we can implement some validation to check the file size and file type.

				
					import { BadRequestException, Injectable } from '@nestjs/common';

@Injectable()
export class FileUploadService {
  handleFileUpload(file: Express.Multer.File) {
    if (!file) {
      throw new BadRequestException('no file uploaded');
    }

    // validate file type
    const allowedMimeTypes = ['image/jpeg', 'image/png', 'application/pdf'];
    if (!allowedMimeTypes.includes(file.mimetype)) {
      throw new BadRequestException('invalid file type');
    }

    // validate file size (e.g., max 5mb)
    const maxSize = 5 * 1024 * 1024;
    if (file.size > maxSize) {
      throw new BadRequestException('file is too large!');
    }

    return { message: 'File uploaded successfully', filePath: file.path };
  }
}

				
			

Now we have configured the necessary steps for file upload.

How to Test the File Upload

When you’re building a feature in your application, testing is an important part. Now we are going to test our application using Postman. You can use any similar tool for testing file upload endpoint.

Send request using postman tool

After making the request using Postman, confirm that the file is uploaded successfully by checking the response. You can also check file-upload-example, you can see that there is a folder named uploads with the file you uploaded.

Conclusion

Now you understand how we can upload files using Multer and NestJs. This is only the basics for you to get started with file upload using Multer in NestJs. You can do more complex features like uploading multiple files and more.

I really enjoyed working with the demo, and I hope that you guys get valuable information from this.

Author

Related tags on EverSoft

Table of Contents

Read Some Blogs