NestJS Module 実装方法

# はじめに
この記事では、NestJS の Module の実装方法について記載します。
また、前提知識となる Controller や Provider については、別の記事に記載しています。

https://qiita.com/Yasushi-Mo/items/a35383ed37f7c8ce46ab

https://qiita.com/Yasushi-Mo/items/36c107ca39ed766c8a08

# 開発環境
開発環境は以下の通りです。

- Windows11
- VSCode
- Node.js 20.5.0
- NestJS 10.0.0
- TypeScript 5.1.3

# Module とは
Module には、Controller や Provider をひとつにまとめる役割があります。
また、以下の図のようにアプリケーション内に複数の Module を持つことができます。

![Modules_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/55c9ca29-83ed-b4fc-2cc4-c5ef4cbb1760.png)
[^1]
[^1]:https://docs.nestjs.com/modules

# Module の実装
```@Module``` デコレーターをつけたクラス内部に ```controllers``` と ```providers``` プロパティを追加することで、Module を実装することができます。

```app.nodule.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

## Module の import
プロパティに ```imports``` を追加することで、他の Module を取り込むことができます。

```app.nodule.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CatsModule } from './modules/cats.module';

@Module({
  imports: [CatsModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

:::note
```imports``` に Module として取り込まず、以下のように Controller、Provider をそれぞれ追加しても同じ動作になります。

```app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CatsController } from './controllers/cats.controller';
import { CatsService } from './services/cats.service';

@Module({
  controllers: [AppController, CatsController],
  providers: [AppService, CatsService],
})
export class AppModule {}
```

ただ、Controller、Provider の数が増えてくると、AppModule が肥大化してしまいます。そのため、先ほどの図のように Module として取り込むことが推奨されています。

:::

## Module の export
プロパティに ```exports``` を追加することで、対象の Module に含まれる Provider を外部の Module に公開できます。

```cats.module.ts
import { Module } from '@nestjs/common';
import { CatsController } from 'src/controllers/cats.controller';
import { CatsService } from 'src/services/cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService],
})
export class CatsModule {}
```

公開すると、対象の Module を取り込んだ Module の Controller や Provider で公開された Provider を利用することができるようになります。

```app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CatsModule } from './modules/cats.module';
import { CatsService } from './services/cats.service';

@Module({
  imports: [CatsModule],
  controllers: [AppController],
  providers: [AppService, CatsService],
})
export class AppModule {}
```

```app.service.ts
import { Injectable } from '@nestjs/common';
import { CatsService } from './services/cats.service';

@Injectable()
export class AppService {
  constructor(private catsService: CatsService) {}

  getHello(): string {
    return 'Hello World!';
  }
}
```

# 参考
- [Modules](https://docs.nestjs.com/modules)