NestJS : Upload pictures and access

Neo Luo
5 min readJun 18, 2024

--

Preface

This chapter mainly introduces nestjsthe use of uploading image resources on the server express multer, FileInterceptor controls the size of uploaded files, and express staticexposes the image resource address by generating a static directory. The front end uploads image resources through postman

Project directory structure

The general project structure is as follows: src/uploadIt is the upload resource module, and the root directory uploadsis the storage location for uploaded resources

nest-upload/
├── src/
│ ├── upload/ (handler upload)
│ │ ├── upload.controller.ts
│ │ ├── upload.module.ts
│ ├── app.module.ts
│ ├── main.ts
├── uploads/ (store upload image)
├── .gitignore
├── package.json
├── tsconfig.json
└── README.md

Final effect of demo: Postman image upload and access

1. Quickly create a nestjs project

Here you can nestjs CLIquickly create a project nest-upload. Click to see how to create a project

nest new nest-upload
cd nest-upload

After successful creation, switch to the project. Since it nestjsis built based on the Express framework, Expressthe package already comes with it and does not need to be installed. Among them multer, @types/multerthe dependent packages need to be installed

npm i multer @types/multer --save

Then nestjs CLIquickly create uploada resource upload module

nest g mo upload # create module
nest g co upload --no-spec # create controller

2. Multer resource upload processing

After uploading the image resource, the service needs to store the resource in the root directory . It needs to determine whether there is a directory uploadsin the startup file. If there is no directory, it will be created automatically.src/main.tsuploadsuploads

// src/main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
+import { join } from 'path';
+import { existsSync, mkdirSync } from 'fs';

async function bootstrap() {
const app = await NestFactory.create(AppModule);
+ const uploadDir = join(process.cwd(), 'uploads');
+ if (!existsSync(uploadDir)) {
+ mkdirSync(uploadDir);
+ }
await app.listen(3000);
}
bootstrap();

upload.module.tsAdd code to process uploaded resources:

// src/upload/upload.module.ts

import { Module } from '@nestjs/common';
import { MulterModule } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
import { extname, join } from 'path';
import { UploadController } from './upload.controller';

// create 'uploads' file to root
const uploadDir = join(process.cwd(), 'uploads');

@Module({
imports: [
MulterModule.register({
storage: diskStorage({
destination: (req, file, cb) => {
cb(null, uploadDir);
},
filename: (req, file, cb) => {
const ext = extname(file.originalname);
const filename = `${Date.now()}${ext}`;
cb(null, filename);
},
}),
fileFilter: (req, file, cb) => {
if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
cb(null, true);
} else {
cb(new Error('Only images are allowed...'), false);
}
},
}),
],
controllers: [UploadController],
providers: [],
})
export class UploadModule { }

fileFilterYou can control the type and size of uploaded files .

Now upload.controller.tscreate an interface for uploading pictures: localhost:3000/upload/uploadImagethe request method is Post, Post bodythe parameters arefile

// src/upload/upload.controller.ts

import { Controller, Post, UploadedFile, UseInterceptors } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';

@Controller('upload')
export class UploadController {

@Post('/uploadImage')
@UseInterceptors(FileInterceptor('file'))
async uploadImage(@UploadedFile() file) {
return "upload success"

}
}

Among them @FileInterceptor, the upload resource decorator provided @UploadedFileby the framework ( see the document )nestjs

3. Postman uploads pictures

First you need to install Postman( resource download ), then create a resource request to upload an image, steps:

Then click Select Filesto select the picture to upload, and click Sendthe button to upload the picture, the effect:

The above is nest-uploadthe resource storage file in the project root directory uploadsto generate uploaded image resources

4. Generate static resource directory

In daily development, when the resource is uploaded successfully, the URL address of the accessible resource needs to be returned. Here we need to modify the src/main.tsgenerated express staticstatic resource directory

// src/main.ts

import { NestFactory } from '@nestjs/core';
+ import * as express from 'express';
...

async function bootstrap() {
...
+ app.use('/uploads', express.static(join(process.cwd(), 'uploads')));
await app.listen(3000);
}
bootstrap();

Modify upload.controller.tsthe image and return the URL address of the corresponding resource after uploading successfully

// src/upload/upload.controller.ts
...

async uploadImage(@UploadedFile() file) {
- return "upload success"
+ const fileUrl = `http://localhost:3000/uploads/${file.filename}`;
+ return {
+ url: fileUrl,
+ };

}
}

PostmanThe effect of using uploaded image resources again :

5. Control the size of uploaded files

It is necessary to control the size of uploaded resources, otherwise the disk will easily run out of space, especially C端when there are a large number of users. By FileInterceptor limitscontrolling the size of uploaded images, the maximum size of images is limited to1MB

// src/upload/upload.controller.ts 

import { Controller, Post, UploadedFile, UseInterceptors } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';

@Controller('upload')
export class UploadController {

@Post('/uploadImage')
@UseInterceptors(FileInterceptor('file', {
+ limits: { fileSize: Math.pow(1024, 2) * 1 }
}))
async uploadImage(@UploadedFile() file) {

const fileUrl = `http://localhost:3000/uploads/${file.filename}`;
return {
url: fileUrl
}
}
}

Test code Here, if you upload a 3MB image, the server will return an error:

advanced

Upload pictures is just the beginning, the real application development also needs to deal with the compression of uploaded resources, resources and data mapping, invalid resource recovery management, interested friends can click to see:

Summarize

Resource uploading is a requirement for most applications. nestjsThrough the ecosystem support FileInterceptor, resources are uploaded, and then the resource address is exposed through the static generation directory. It is a framework encapsulated on the basis, so the project does not need to install package dependencies and can be used directlyUploaded File express nestj

--

--

Neo Luo

I am a full stack developer, engaged in development for more than 10 years, developing e-commerce, tourism, finance, web3, ai, I will share more