반응형
Multer
Multer는 Node.js에서 파일 업로드를 처리하는 미들웨어로, Express와 NestJS 같은 프레임워크와 함께 자주 사용된다
멀티파트 폼 데이터(multipart/form-data)를 처리하며, 업로드된 파일을 요청 객체(req.file 또는 req.files)에 추가해준다
이를 통해 서버에서 업로드된 파일을 쉽게 다룰 수 있다
특징
- 멀티파트 폼 데이터 지원
- Multer는 일반적인 JSON 또는 URL-encoded 데이터가 아닌, 파일과 데이터를 함께 전송하는 멀티파트 폼 데이터를 처리한다.
- 스토리지 옵션 제공
- Multer는 업로드된 파일을 처리할 위치를 설정할 수 있다.
- 메모리 저장소: 파일이 메모리에 버퍼 형태로 저장
- 디스크 저장소: 파일이 지정된 디렉토리에 저장
- Multer는 업로드된 파일을 처리할 위치를 설정할 수 있다.
- 파일 필터링
- 업로드된 파일의 형식, 크기, 이름 등을 필터링하여 원하는 파일만 처리할 수 있다.
- 다중 파일 업로드 지원
- Multer는 한 번에 여러 파일을 업로드할 수 있도록 지원함
설치 명령어
npm i multer @types/multer
Multer 설정 코드
common.mudule.ts
import { BadRequestException, Module } from '@nestjs/common';
import { CommonService } from './common.service';
import { CommonController } from './common.controller';
import { MulterModule } from '@nestjs/platform-express';
import { extname } from 'path';
import * as multer from 'multer';
import { POST_IMAGE_PATH, TEMP_FOLDER_PATH } from './const/path.const';
import { v4 as uuid } from 'uuid';
import { AuthModule } from '../auth/auth.module';
import { UsersModule } from '../users/users.module';
@Module({
imports: [
AuthModule,
UsersModule,
MulterModule.register({
// 파일 크기 제한
limits: {
// 바이트 단위로 입력
fileSize: 10000000,
},
fileFilter: (req, file, cb) => {
/*
cb(에러 | bool)
첫번쨰 파라미터는 에러가 있을경우 에러를 넣어줌
두번째는 파일을 받을지 말지 boolean 을 넣어줌
*/
// xxx.jpg -> .jpg
const ext = extname(file.originalname);
if (ext !== '.jpg' && ext !== '.jpeg' && ext !== '.png') {
return cb(new BadRequestException('jpg, jpeg, png 파일만 업로드 가능'), false);
}
return cb(null, true);
},
storage: multer.diskStorage({
destination: (req, file, cb) => {
cb(null, TEMP_FOLDER_PATH);
},
filename: (req, file, cb) => {
cb(null, `${uuid()}${extname(file.originalname)}`);
},
}),
}),
],
controllers: [CommonController],
providers: [CommonService],
exports: [CommonService],
})
export class CommonModule {}
코드 설명
1. 파일 업로드 크기 제한
limits: {
fileSize: 10000000, // 최대 파일 크기: 10MB (10,000,000 바이트)
},
- 업로드 가능한 파일의 최대 크기를 제한
- fileSize가 초과되면 BadRequestException 과 같은 에러가 발생하며 파일 업로드가 중단됨
2. 파일 필터링
fileFilter: (req, file, cb) => {
const ext = extname(file.originalname);
if (ext !== '.jpg' && ext !== '.jpeg' && ext !== '.png') {
return cb(new BadRequestException('jpg, jpeg, png 파일만 업로드 가능'), false);
}
return cb(null, true);
},
- fileFilter 는 파일이 업로드되기 전에 파일의 유효성을 검증하는 역할을 함
- file.originalname의 확장자를 추출하여 .jpg, .jpeg, .png 형식만 허용함
- 다른 파일 형식이 업로드되면 BadRequestException 을 반환하며 업로드를 중단
3. 저장소 설정
storage: multer.diskStorage({
destination: (req, file, cb) => {
cb(null, TEMP_FOLDER_PATH);
},
filename: (req, file, cb) => {
cb(null, `${uuid()}${extname(file.originalname)}`);
},
}),
- **storage**는 업로드된 파일이 저장되는 위치와 이름을 설정함
3-1. 저장위치
destination: (req, file, cb) => {
cb(null, TEMP_FOLDER_PATH);
},
- TEMP_FOLDER_PATH에 파일을 저장함
3-2. 파일이름
filename: (req, file, cb) => {
cb(null, `${uuid()}${extname(file.originalname)}`);
},
- 파일 이름은 **UUID (Universally Unique Identifier)**를 생성하여 설정함
- 예: 123e4567-e89b-12d3-a456-426614174000.jpg
- 확장자는 원본 파일 이름에서 추출된 값(extname(file.originalname))을 그대로 사용함
- 예: .jpg, .png
4. 예외 처리
return cb(new BadRequestException('jpg, jpeg, png 파일만 업로드 가능'), false);
- 업로드 제한 조건을 만족하지 않는 경우 BadRequestException을 발생시킨다.
5. 업로드 결과
게시물 등록 Multer 적용 코드
post.controller.ts
@Post()
@UseGuards(AccessTokenGuard)
@UseInterceptors(FileInterceptor('image'))
postPost(
@User('id') userId: number,
@Body() body: CreatePostDto,
@UploadedFile() file?: Express.Multer.File
) {
return this.postsService.createPost(userId, body, file?.filename);
}
- @UseInterceptors(FileInterceptor('image'))
- Multer를 사용하여 파일 업로드를 처리
- 클라이언트가 전송한 파일이 HTTP 요청에서 image라는 이름의 필드로 첨부됨
- @UploadedFile() file?: Express.Multer.File
- 업로드된 파일 정보를 Multer에서 가져옴
- 파일이 업로드되지 않았다면 file은 undefined 가 됨
post.service.ts
Static File Serving
NestJS에서 정적 파일을 제공하기 위해 사용하는 모듈
애플리케이션이 지정된 디렉토리의 파일을 HTTP 요청으로 클라이언트에 서빙할 수 있다
설치 명령어
npm i @nestjs/serve-static
사용 방법
app.module.ts
// imports: [] 에 추가
ServeStaticModule.forRoot({
// 4022.jpg
// http://localhost:3000/public/posts/4022.jpg
// http://localhost:3000/posts/4022.jpg
rootPath: PUBLIC_FOLDER_PATH,
serveRoot: '/public',
}),
- rootPath
- 정적 파일이 저장된 디렉토리의 절대 경로를 지정
- 예: PUBLIC_FOLDER_PATH가 /uploads로 설정된 경우, /uploads 디렉토리 내의 파일을 서빙하게 된다.
- serveRoot
- 정적 파일에 접근하기 위한 URL 경로(prefix)를 지정
- 예: serveRoot: '/public'으로 설정하면, 정적 파일은 http://<호스트>:<포트>/public 경로를 통해 접근할 수 있다.
동작 원리
예시 동작
1. 디렉토리 구조
/uploads
├── posts
│ ├── 4022.jpg
│ ├── 1234.png
- PUBLIC_FOLDER_PATH가 /uploads로 설정되었다고 가정.
- 정적 파일 요청
- 클라이언트가 http://localhost:3000/public/posts/4022.jpg로 요청을 보냄.
- 파일 매핑
- 서버는 /uploads/posts/4022.jpg 경로에서 파일을 검색
- 파일이 존재한다면 클라이언트로 해당 파일을 반환
- 결과
- 클라이언트는 브라우저 또는 기타 클라이언트에서 4022.jpg 이미지를 확인할 수 있다
반응형
'nestJS' 카테고리의 다른 글
NestJS | Class Validator, Transformer (1) | 2024.11.20 |
---|---|
NestJS | Guard (0) | 2024.11.20 |
NestJS | Pipe (0) | 2024.11.20 |
NestJS | TypeORM Table Inheritance (0) | 2024.11.12 |
NestJS | TypeORM Entity Embedding (2) | 2024.11.12 |