> For the complete documentation index, see [llms.txt](https://jakekwak.gitbook.io/nestjs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jakekwak.gitbook.io/nestjs/techniques/file-upload.md).

# File upload

## File upload

파일 업로드를 처리하기 위해 Nest는 [multer](https://github.com/expressjs/multer) 미들웨어를 사용합니다. 이 미들웨어는 완전히 구성 가능하며 애플리케이션 요구 사항에 따라 작동을 조정할 수 있습니다.

Multer는 주로 파일 업로드에 사용되는 `multipart/form-data`를 처리하기위한 미들웨어입니다.

> warning **경고** Multer는 멀티 파트 ( `multipart/form-data`)가 아닌 폼을 처리하지 않습니다. 또한 이 패키지는 `FastifyAdapter`와 함께 작동하지 않습니다.

## Basic example

단일 파일을 업로드하고 싶을 때는 단순히 `FileInterceptor()`를 핸들러에 연결한 다음 `@UploadedFile()`데코레이터를 사용하여 `요청(request)`에서 `파일(file)`을 가져옵니다.

```typescript
@@filename()
@Post('upload')
@UseInterceptors(FileInterceptor('file'))
uploadFile(@UploadedFile() file) {
  console.log(file);
}
@@switch
@Post('upload')
@UseInterceptors(FileInterceptor('file'))
@Bind(UploadedFile())
uploadFile(file) {
  console.log(file);
}
```

> info **힌트** `FileInterceptor()`데코레이터는 `@nestjs/platform-express` 패키지에서 내보내고`@UploadedFile()`은 `@nestjs/common`에서 내 보냅니다.

`FileInterceptor()`는`fieldName` (파일을 보유한 HTML 형식의 필드를 가리킴)과 선택적 `options` 객체의 두 인수를 취합니다. 이 `MulterOptions`는 multer 생성자에 전달된 것과 동일합니다 (자세한 내용은 [여기](https://github.com/expressjs/multer#multeropts)).

## Array of files

파일 배열을 업로드하기 위해 `FilesInterceptor()`를 사용합니다. 이 인터셉터는 세 가지 인자를 취합니다. `fieldName` (동일하게 유지됨), `maxCount`는 동시에 업로드할 수 있는 최대 파일 수이며 선택적인 `MulterOptions` 객체입니다. 또한 `request` 객체에서 파일을 선택하기 위해 `@UploadedFiles()`데코레이터를 사용합니다

```typescript
@@filename()
@Post('upload')
@UseInterceptors(FilesInterceptor('files'))
uploadFile(@UploadedFiles() files) {
  console.log(files);
}
@@switch
@Post('upload')
@UseInterceptors(FilesInterceptor('files'))
@Bind(UploadedFiles())
uploadFile(files) {
  console.log(files);
}
```

> info **힌트** `FilesInterceptor()` 데코레이터는 `@nestjs/platform-express` 패키지에서 내보내고`@UploadedFiles()`는 `@nestjs/common`에서 내 보냅니다.

## Multiple files

여러 필드 (모두 다른 키로)를 업로드하기 위해 `FileFieldsInterceptor()` 데코레이터를 사용합니다.

```typescript
@@filename()
@Post('upload')
@UseInterceptors(FileFieldsInterceptor([
  { name: 'avatar', maxCount: 1 },
  { name: 'background', maxCount: 1 },
]))
uploadFile(@UploadedFiles() files) {
  console.log(files);
}
@@switch
@Post('upload')
@Bind(UploadedFiles())
@UseInterceptors(FileFieldsInterceptor([
  { name: 'avatar', maxCount: 1 },
  { name: 'background', maxCount: 1 },
]))
uploadFile(files) {
  console.log(files);
}
```

## Any files

모든 필드를 업로드하려면 (다른 키를 사용하지만 알 필요는 없습니다) `AnyFilesInterceptor()`데코레이터를 사용합니다.

```typescript
@@filename()
@Post('upload')
@UseInterceptors(AnyFilesInterceptor())
uploadFile(@UploadedFiles() files) {
  console.log(files);
}
@@switch
@Post('upload')
@Bind(UploadedFiles())
@UseInterceptors(AnyFilesInterceptor())
uploadFile(files) {
  console.log(files);
}
```

## Default options

[multer](https://github.com/expressjs/multer) 동작을 사용자 정의하기 위해 `MulterModule`을 등록할 수 있습니다. [여기](https://github.com/expressjs/multer#multeropts)에 나열된 모든 옵션을 지원합니다.

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

## Async configuration

모듈 옵션을 미리 전달하는 대신 비동기식으로 전달하려는 경우가 종종 있습니다. 이 경우, 비동기 데이터를 처리하는 다양한 방법을 제공하는 `registerAsync()` 메소드를 사용하십시오.

가능한 첫 번째 방법은 팩토리 기능을 사용하는 것입니다.

```typescript
MulterModule.registerAsync({
  useFactory: () => ({
    dest: '/upload',
  }),
});
```

분명히, 우리 팩토리는 다른 모든 것처럼 행동합니다 ( `비동기`일 수도 있고 `주입`을 통해 의존성을 주입할 수도 있습니다).

```typescript
MulterModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    dest: configService.getString('MULTER_DEST'),
  }),
  inject: [ConfigService],
});
```

또는 팩토리 대신 클래스를 사용할 수 있습니다.

```typescript
MulterModule.registerAsync({
  useClass: MulterConfigService,
});
```

위의 구성은 `MulterModule`내에서 `MulterConfigService`를 인스턴스화 하고 이를 활용하여 옵션 개체를 만듭니다. `MulterConfigService`는 `MulterOptionsFactory` 인터페이스를 구현해야 합니다.

```typescript
@Injectable()
class MulterConfigService implements MulterOptionsFactory {
  createMulterOptions(): MulterModuleOptions {
    return {
      dest: '/upload',
    };
  }
}
```

`MulterModule` 내에 `MulterConfigService`가 작성되는 것을 막고 다른 모듈에서 가져온 제공자를 사용하려면`useExisting` 구문을 사용할 수 있습니다.

```typescript
MulterModule.registerAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

`MulterModule`은 가져온 모듈을 검색하여 자체적으로 인스턴스화하는 대신 이미 생성 된 `ConfigService`를 재 사용하기 위해 가져온 모듈을 찾습니다.
