1. Multer 설치와 설정


파일 업로드를 처리하기 위해 Nest는 express용 multer 미들웨어 패키지를 사용한다.

설치

npm i -D @types/multer

1-1) main.ts

import { HttpExceptionFilter } from 'src/common/exceptions/http-exception.filter';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';
import { SwaggerModule, DocumentBuilder, OpenAPIObject } from '@nestjs/swagger';
import * as expressBasicAuth from 'express-basic-auth';
import { NestExpressApplication } from '@nestjs/platform-express';
import * as path from 'path';
async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);
  // NestExpressApplication으로 nest뿐만 아니라 express의 모듈도 사용한다.
  app.useGlobalPipes(new ValidationPipe()); // class validation 등록
  app.useGlobalFilters(new HttpExceptionFilter()); // global filter 사용
  app.use(
    ['/docs', '/docs-json'],
    expressBasicAuth({
      challenge: true,
      users: {
        [process.env.SWAGGER_USER]: process.env.SWAGGER_PASSWORD,
      },
    }),
  ); // swagger에 아무나 접근하면 안되기 때문에 암호를 걸어둔다.

  const config = new DocumentBuilder()
    .setTitle('C.I.C')
    .setDescription('cat')
    .setVersion('1.0.0')
    .build(); // swagger 설정

  app.useStaticAssets(path.join(__dirname, './common', 'uploads'), {
    prefix: '/media',
  }); // express의 파일 업로드 기능을 사용한다. NestFactory에 NestExpressApplication를 작성한 이유다.

  const document: OpenAPIObject = SwaggerModule.createDocument(app, config); // swagger 생성
  SwaggerModule.setup('docs', app, document); // swagger 등록

  // cors error 해결
  app.enableCors({
    origin: true, // 모든 주소에서 요청을 보낼 수 있기 때문에 개발이 끝나면 url으로 작성한다.
    credentials: true,
  });

  const PORT = process.env.PORT;
  await app.listen(PORT);
}
bootstrap();

nest의 파일업로드 기능은 express의 모듈에서 사용하는 것이기 때문에 NestFactory에 NestExpressApplication를 넣어 사용한다.

app.useStaticAssets(path.join(__dirname, './common', 'uploads'), {
    prefix: '/media',
  }); 
  // express의 파일 업로드 기능을 사용한다.
  // NestFactory에 NestExpressApplication를 작성한 이유다.

useStaticAssets은 express 모듈이라 NestExpressApplication로 설정하지 않으면 사용할 수 없다.

파일 업로드를 위한 모듈들을 세팅해주었으니 실제 로직을 작성해서 프로필 사진을 바꿔보자!

1-2) cats.module.ts

import { Module, forwardRef } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { CatsController } from './controllers/cats.controller';
import { Cat, CatSchema } from './cats.schema';
import { CatsService } from './services/cats.service';
import { CatsRepository } from './cats.repository';
import { AuthModule } from 'src/auth/auth.module';
import { MulterModule } from '@nestjs/platform-express';

@Module({
  imports: [
    MulterModule.register({
      dest: './upload',
    }), // file upload 관련 모듈
    MongooseModule.forFeature([{ name: Cat.name, schema: CatSchema }]),
    forwardRef(() => AuthModule), // 순환 모듈 문제 (CatsModule에서 AuthModule imports, AuthModule에서 CatsModule imports)
  ], // schema 등록
  controllers: [CatsController],
  providers: [CatsService, CatsRepository],
  exports: [CatsService, CatsRepository],
  // exports => 외부 모듈에서 사용할 수 있게함, provider는 캡슐화되어있기 때문에 다른 모듈에서 공개적으로 사용할 수 있게 하려면 export에다 넣어야한다.
})
export class CatsModule {}

MulterModule.register({
      dest: './upload',
    })

파일 업로드 기능 사용을 위해 cats.module.ts에서 imports로 파일 업로드에 관한 모듈을 가져온다.