NEST 폴더구조

aiden·2022년 5월 29일

Before Getting Started
Rest API, TypeORM(MySQL), JWT 인증을 사용하는 프로젝트를 기준으로 설명합니다.

GraphQL을 사용하거나 다른 종류의 인증 방식을 사용하셔도 크게 프로젝트 구조가 달라지지 않으니 걱정마세요!

Directory Structure 📂
프로젝트를 구성하는 directory들입니다. 각 section의 용도는 아래에서 더 자세히 설명하겠습니다.

src
├── auth
│ ├── decorators
│ ├── dtos
│ ├── exceptions
│ ├── guards
│ └── interfaces
├── common
│ ├── decorators
│ ├── dtos
│ ├── entities
│ ├── exceptions
│ ├── helpers
│ └── interfaces
├── config
│ ├── app
│ ├── database
│ │ └── mysql
│ └── jwt
├── database
│ ├── migrations
├── modules
│ ├── item
│ │ ├── brands
│ │ │ ├── entities
│ │ │ ├── interfaces
│ │ │ └── repositories
│ │ └── items
│ │ ├── entities
│ │ ├── interfaces
│ │ └── repositories
│ └── user
│ └── users
│ ├── entities
│ ├── interfaces
│ └── repositories
├── providers
| ├── aws
│ │ ├── s3
│ │ └── sqs
| ├── cache
│ │ └── redis
│ ├── database
│ │ └── postgres
│ └── elasticsearch
│ ├── helpers
│ └── types
├── app.controller.ts
├── app.module.ts
└── main.ts
Config ⚙️
config/ 폴더에는 상황에 따라 필요한 환경변수들이 들어있습니다.

@nestjs/config를 사용합니다.

src/config
├── app
│ ├── config.module.ts
│ ├── config.service.ts
│ ├── configuration.ts
│ └── index.ts
├── database
│ └── mysql
│ ├── config.module.ts
│ ├── config.service.ts
│ ├── configuration.ts
│ └── index.ts
└── jwt
├── config.module.ts
├── config.service.ts
├── configuration.ts
└── index.ts
각 파일의 용도는 다음과 같습니다.

index.ts: 다른 모듈들을 export하는 barrel
configuration.ts: process.env 환경 변수들을 읽어 @nestjs/config에 등록합니다.
config.service.ts: 외부 모듈들에 각 config 값들을 노출시켜주는 인터페이스 역할을 수행합니다.
config.module.ts: ConfigModule.forRoot를 호출하고 service를 외부 모듈들에 export합니다.

Providers 📥
Provider는 외부 provider 엔진과 앱을 연결시켜주는 모듈들로 구성됩니다. (e.g. 데이터베이스, 검색엔진, …)

설정 및 연결을 위한 Module 파일 1개로 구성되는 경우도 있고, 필요에 따라 그 모듈을 잘 활용할 수 있도록 도와주는 Service를 추가할 수도 있습니다.

이때 Service에는 provider 자체를 활용하는 기능만 추가하고, 비즈니스 로직은 포함하지 않습니다.

src/providers
├── aws
│ ├── s3
│ │ ├── index.ts
│ │ ├── s3.module.ts
│ │ └── s3.service.ts
│ └── sqs
│ ├── index.ts
│ └── sqs.module.ts
├── cache
│ └── redis
│ ├── redis.module.ts
│ ├── redis.service.ts
│ └── index.ts
├── database
│ └── mysql
│ ├── index.ts
│ └── mysql.module.ts
└── elasticsearch
├── helpers
├── types
├── elasticsearch.module.ts
├── elasticsearch.service.ts
└── index.ts


import { Module } from '@nestjs/common';
import {
  ElasticsearchModule,
  ElasticsearchModuleAsyncOptions,
  ElasticsearchModuleOptions,
} from '@nestjs/elasticsearch';

import {
  ElasticsearchConfigModule,
  ElasticsearchConfigService,
} from '@config/providers/elasticsearch';

import { ElasticsearchService } from './provider.service';

@Module({
  imports: [
    ElasticsearchModule.registerAsync({
      imports: [ElasticsearchConfigModule],
      useFactory: async (configService: ElasticsearchConfigService) =>
        ({
          node: configService.node,
          auth: {
            username: configService.username,
            password: configService.password,
          },
        } as ElasticsearchModuleOptions),
      inject: [ElasticsearchConfigService],
    } as ElasticsearchModuleAsyncOptions),
  ],
  providers: [ElasticsearchService],
  exports: [ElasticsearchService],
})
export class ElasticsearchProviderModule {}

생성한 모듈을 AppModule에서 import하시면 됩니다.

@Module({
  imports: [
    ... ,
    ElasticsearchProviderModule,
    ... ,
  ],
  controllers: [AppController],
})
export class AppModule {
대부분의 Provider 모듈(typeorm, redis, …)들을 위와 같은 방식으로 등록할 수 있습니다.

(forRootAsync, registerAsync 대신 forRoot, register 메소드를 사용해 동기적으로 등록하는 방법도 있지만 @nestjs/config에 등록된 환경변수 값을 활용할 수 없기 때문에 많은 경우 확장성 측면에서 문제가 있습니다.)


References
https://sumini.dev/guide/019-nestjs-directory-structure/
profile
웹/앱 백엔드 개발자

0개의 댓글