DEV Community

José Thomaz
José Thomaz

Posted on

Fastify + NestJS file upload

We all know that Fastify is faster than Express, and for this reason, many people are switching from the Express micro-framework to Fastify. However, sometimes you might want to build a more robust system with better tooling. In such cases, you can choose between Meteor, Adonis, or NestJS. Many developers opt for NestJS because it is reminiscent of SpringBoot from Java and is built on top of Express. However, it also offers compatibility with Fastify, providing developers with the best of both worlds.

I always choose NestJS with Fastify, it works incredibly well in most cases. However, even though NestJS offers full support for Fastify, not everything is rosy, uploading files can be a little bit tricky in a NestJS environment powered by Fastify. So, in this article, I am gonna teach you how to do this, as it is not present in the official docs.

Installing the dependencies

First, you need to install the necessary packages. You can do this using your preferred package manager. Here are the packages you need:

  • @fastify/multipart
  • @blazity/nest-file-fastify

To install the packages, run one of the following commands:

yarn add @fastify/multipart @blazity/nest-file-fastify

or

npm install @fastify/multipart @blazity/nest-file-fastify

Modify your main.ts file

  1. Import the @fastify/multipart package
  2. Register the package within Fastify

The code should look something like this:

// other imports
import multiPart from '@fastify/multipart';

/**
 * Main function
 */
async function bootstrap(): Promise<void> {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter({
      logger: true,
    }),
  );

    await app.register(multiPart);
  const httpAdapterHost = app.get(HttpAdapterHost);

    // rest of the code ...

  await app.listen(3333, process.env.HOST);
}
Enter fullscreen mode Exit fullscreen mode

Create a route for uploading files in a NestJS controller

Now, you need to create a controller with a route for handling file uploads. Here’s an example of how you can do it:

import {
  FileFieldsInterceptor,
  MemoryStorageFile,
  UploadedFiles,
} from '@blazity/nest-file-fastify';
import {
  Body,
  Controller,
  Post,
  UseInterceptors,
} from '@nestjs/common';

@Controller('example')
export class ExampleController {

    /**
   * Route for uploading files
   */
  @Post('/upload')
  @UseInterceptors(
    FileFieldsInterceptor([
      { name: 'image', maxCount: 1 },
      { name: 'imageTwo', maxCount: 1 },
    ])
  )
  async register(
    @Body() data: Record<string, unknown>,   // other data that you might want to pass along with the files
    @UploadedFiles()
    files: { image?: MemoryStorageFile[0]; imageTwo?: MemoryStorageFile[0] }
  ): Promise<void> {
    Object.values(files).forEach((file) => {
      this.s3Service.uploadFile(file[0]);
    });
  }

}
Enter fullscreen mode Exit fullscreen mode

In this example, the @Post('/upload') route is set up to handle file uploads. The FileFieldsInterceptor is used to specify the expected file fields in the request. In this case, we expect two image files, image, and imageTwo, each with a maximum count of 1.

The uploaded files are then passed to the register method, where they can be processed as needed. In this example, the files are uploaded to an S3 service.

That’s it! Now you can send a multipart/form-data request to your NestJS server, and the files will be handled accordingly.

Top comments (2)

Collapse
 
pepefeliblu profile image
Juan Rueda

There must be something missing here as The @blazity/nest-file-fastify does not contain certain definitions for Busboy and it is calling the deprecated fastify/multipart.

I tried looking for issues similar to this and I am not able to find any solution.

Collapse
 
97hyun profile image
97-Hyun

Thank you so much! I saw this when I was wondering if I should use only nestjs again because I couldn't find a document about nestjs + fastify file upload Your writing has helped me