728x90

NestJS에서 파일 업로드를 처리하는 가장 일반적인 방법은 @nestjs/platform-express에서 제공하는 MulterModule을 사용하는 것입니다. 이 모듈은 내부적으로 Express의 파일 업로드 미들웨어인 multer를 래핑하여 NestJS의 DI 시스템과 통합되도록 합니다.
1. 🛠️ 사전 준비 및 설치
1.1. Multer 설치
MulterModule은 multer 패키지에 의존하므로, 먼저 이를 설치해야 합니다.
npm install multer
1.2. MulterModule 등록
애플리케이션의 루트 모듈 또는 파일 업로드가 필요한 모듈에 MulterModule을 등록합니다.
728x90
2. 📝 MulterModule.register() 설정
MulterModule을 등록할 때, register() 메서드에 multer의 옵션 객체를 전달하여 파일의 저장 방식, 파일 크기 제한, 인코딩 등을 설정합니다.
2.1. 로컬 저장소 설정 (Disk Storage)
파일을 서버의 로컬 파일 시스템에 저장하는 가장 기본적인 설정입니다.
// src/app.module.ts
import { Module } from '@nestjs/common';
import { MulterModule } from '@nestjs/platform-express';
import * as path from 'path';
@Module({
imports: [
MulterModule.register({
// 💡 파일을 서버의 디스크에 저장하도록 설정
dest: path.join(__dirname, '..', 'uploads'), // 💡 저장될 경로 지정
}),
],
// ...
})
export class AppModule {}
2.2. 로컬 저장소의 고급 설정 (storage 옵션)
dest 대신 storage 옵션을 사용하면 파일 저장 경로와 파일 이름을 직접 제어할 수 있습니다. 이는 파일 중복을 방지하고 파일 관리의 유연성을 높입니다.
// src/app.module.ts (MulterModule 설정 업데이트)
import { MulterModule } from '@nestjs/platform-express';
import { diskStorage } from 'multer'; // 💡 multer의 디스크 저장소 함수
import * as path from 'path';
@Module({
imports: [
MulterModule.register({
storage: diskStorage({
// 1. 💡 저장 경로 설정
destination: (req, file, cb) => {
// 파일을 저장할 폴더 (예: /uploads)
cb(null, path.join(__dirname, '..', 'uploads'));
},
// 2. 💡 파일 이름 설정
filename: (req, file, cb) => {
// 파일명 중복을 방지하기 위해 파일 이름을 변경
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
// 원본 파일 확장자 추출
const ext = path.extname(file.originalname);
// 최종 파일 이름: 타임스탬프-랜덤값.확장자
cb(null, `${file.fieldname}-${uniqueSuffix}${ext}`);
},
}),
}),
],
// ...
})
export class AppModule {}
3. 🛡️ 파일 크기 및 유효성 설정
MulterModule의 register() 옵션 내에서 파일의 크기 제한 및 필터링을 설정할 수 있습니다.
3.1. 파일 크기 제한 (limits)
단일 파일 또는 전체 요청의 파일 크기를 제한하여 서비스 거부 공격(DoS)을 방지합니다.
// MulterModule.register() 옵션 내부
MulterModule.register({
// ... storage 설정
limits: {
// 💡 단일 파일 최대 크기: 5MB (5 * 1024 * 1024 bytes)
fileSize: 5 * 1024 * 1024,
// 💡 최대 파일 개수: 10개
files: 10,
},
}),
3.2. 파일 필터링 (fileFilter)
특정 파일 형식(MIME Type)만 허용하도록 필터링하여 보안을 강화합니다.
// MulterModule.register() 옵션 내부
MulterModule.register({
// ... storage 설정
fileFilter: (req, file, cb) => {
// 💡 이미지 파일(jpg, jpeg, png)만 허용하는 필터링 로직
if (file.mimetype.match(/\/(jpg|jpeg|png|gif)$/)) {
// true: 허용 (파일 업로드 계속)
cb(null, true);
} else {
// false: 거부 (파일 업로드 중단 및 에러 반환)
cb(new Error('지원하지 않는 파일 형식입니다. (JPG, PNG, GIF만 가능)'), false);
}
},
}),
728x90
4. 🔗 컨트롤러에 적용
MulterModule이 설정되면, 이제 컨트롤러 핸들러에 @UseInterceptors() 데코레이터와 FileInterceptor를 사용하여 업로드된 파일을 처리할 수 있습니다.
// src/users/users.controller.ts
import { Controller, Post, UseInterceptors, UploadedFile } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
@Controller('users')
export class UsersController {
@Post('avatar')
// 💡 단일 파일 업로드 인터셉터 적용: 'avatar'는 폼 데이터의 필드 이름
@UseInterceptors(FileInterceptor('avatar'))
uploadAvatar(@UploadedFile() file: Express.Multer.File) {
// 파일이 성공적으로 업로드 및 저장되면, file 객체에 정보가 담겨 전달됩니다.
console.log(file);
return {
filename: file.filename,
path: file.path
};
}
}
728x90
'Nest.js를 배워보자 > 9. NestJS에서 파일 업로드 & 관리 — S3, 로컬 저장소' 카테고리의 다른 글
| 대용량 파일 처리 전략 (0) | 2025.12.02 |
|---|---|
| NestJS 파일 유효성 검사 (Validation Pipe) (0) | 2025.12.02 |
| AWS S3 업로드: 클라우드 파일 관리 (0) | 2025.12.02 |