NestJS File Uploading Using Multer

How to develop a simple file-uploading app

Gabriel Tanner
Aug 27, 2019 · 5 min read
Image for post
Image for post
Photo by JF Martin on Unsplash

This guide will show you how you can implement file uploading into your NestJS application and the things you should keep in mind when doing so. You will develop an application with three endpoints that will do the following:

  • Upload an image;
  • Upload multiple images;
  • Get the image using the image path.

You will also add custom utilities to edit the file name and validate the file upload for images.

So without wasting any further time, let’s get into it.

Setup

The first thing you need to do is create a NestJS project that will hold our fileserver. For that, you need to open your terminal and run the following command:

nest new nest-file-uploading && cd nest-file-uploading

This creates a new directory called nest-file-uploading and initializes it with a standard NestJS configuration.

With the directory in place, you can go ahead and install the needed dependencies for the application using the following commands:

npm install @nestjs/platform-express --save
npm install @types/express -D

The last thing you need to do before jumping into coding is create the files and folders needed for the project. This is very simple because the application only needs one more file.

mkdir src/utils
touch src/utils/file-uploading.utils.ts

To start the app, you can now execute npm run start:dev in your terminal.

Uploading Files

Now that you have completed the setup process, you can go ahead and start implementing the actual functionality. Let’s start by importing the MulterModule in your AppModule so you can use Multer in your other files.

Here you import the MulterModule from @nestjs/platform-express and add it to your imports statement. You also define the destination in which the files will be saved when an upload occurs.

Note: This destination starts at the root path of the project, not the src folder.

The next step is to implement the actual uploading functionality, which is rather simple. You simply need to add a FileInterceptor() to a normal post request handler and then pull out the file from the request using the @UploadedFile() decorator.

The FileInterceptor takes two arguments: a fieldName and an optional options object, which you will use later to check for the correct file types and give the file a custom name in the directory.

Uploading multiple files at once is almost the same; you just need to use the FilesInterceptor instead and pass an extra argument of the maximum number of files.

That was simple. The only problem here is that the user can upload every file type regardless of the file extension, which doesn’t suit all projects and that the file name is just some random number.

Let’s fix that by implementing some utilities in your file-upload.utils.ts file.

First, let’s implement a file type filter that only allows images to be uploaded.

Here you create a middleware function, which checks if the file type is an image. If so it returns true, and the image will be uploaded. If not, you throw an error and return false for the callback.

The editFileName function has the same structure but creates a custom filename using the original name, the file extension, and four random numbers.

Now that you have created these two middleware functions, it’s time to use them in your app.controller.ts file. For that you just need to add an extra configuration object to the FileInterceptor, which then looks like this:

Lastly you will add a get route, which will take the image path as an argument and return the image using the sendFile method.

@Get(':imgpath')
seeUploadedFile(@Param('imgpath') image, @Res() res) {
return res.sendFile(image, { root: './files' });
}

Testing the Application

Now that you have finished your application, it’s time to test it by sending an HTTP request to your endpoint. This can be done using the curl command in the terminal or by using an HTTP client software like Postman or Insomnia. I personally use Insomnia, but it should be almost the same in Postman.

Start the server using the following command:

npm run start

As indicated by the terminal output, the server is now running on http://localhost:3000. To test the API you now only need to create a new HTTP request and change the request body to multipart so you can upload files.

Image for post
Image for post

Here you set the destination to http://localhost:3000 and add an image to the request body. This can be done by clicking on the arrow next to the checkbox and selecting file.

On the right, you can see the response with the original file name and the new file name on the server.

Note: The new file name is later used to get the images from the server.

Image for post
Image for post

Here you do the same, but upload multiple files on the /multiple endpoint.

Image for post
Image for post

Getting files is also a simple process. You just need to send a get request to the API with the file name you got from the post request as a parameter.

The full code for the project can also be found on my GitHub.

Conclusion

You made it all the way until the end! I hope that this article helped you understand file uploading in NestJS.

If you have any questions or feedback, let me know.

Better Programming

Advice for programmers.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store