NestJSでモジュール(Modules)を作成および管理する:モジュール間の依存関係と通信

モジュールはNestJSのコアビルディングブロックであり、コードを整理し依存関係を管理するのに役立ちます。この記事では、NestJSでモジュールを作成および管理する方法について説明し、モジュール間の依存関係と通信を探り、複雑なプロジェクトにおけるモジュールの組織化と依存管理を示すサンプルコードを提供します。

モジュールの作成と組織化

モジュールの作成

NestJSでは、モジュールはデコレーター @Module() を使用して定義されます。以下の例は、シンプルな UsersModule を作成する方法を示しています:

users/users.module.ts
1
import { Module } from "@nestjs/common";
2
import { UsersService } from "./users.service";
3
import { UsersController } from "./users.controller";
4
5
@Module({
6
providers: [UsersService],
7
controllers: [UsersController],
8
})
9
export class UsersModule {}

モジュールの組織化

典型的なNestJSプロジェクトには複数のモジュールが含まれ、それぞれが異なる機能を担当します。例えば、AuthModule は認証を処理し、ProductsModule は製品管理を処理します。

app.module.ts
1
import { Module } from "@nestjs/common";
2
import { UsersModule } from "./users/users.module";
3
import { AuthModule } from "./auth/auth.module";
4
import { ProductsModule } from "./products/products.module";
5
6
@Module({
7
imports: [UsersModule, AuthModule, ProductsModule],
8
})
9
export class AppModule {}

モジュール間の依存関係

モジュールのエクスポートとインポート

モジュールは exports プロパティを使用して提供するサービスをエクスポートでき、他のモジュールがこれらのサービスをインポートして使用できます。以下の例は、UsersService をエクスポートし、AuthModuleUsersModule をインポートする方法を示しています:

users/users.module.ts
1
import { Module } from "@nestjs/common";
2
import { UsersService } from "./users.service";
3
import { UsersController } from "./users.controller";
4
5
@Module({
6
providers: [UsersService],
7
controllers: [UsersController],
8
exports: [UsersService], // UsersServiceをエクスポート
9
})
10
export class UsersModule {}
11
12
// auth/auth.module.ts
13
import { Module } from "@nestjs/common";
14
import { AuthService } from "./auth.service";
15
import { UsersModule } from "../users/users.module";
16
17
@Module({
18
imports: [UsersModule], // UsersModuleをインポート
19
providers: [AuthService],
20
})
21
export class AuthModule {}

モジュール間の通信

モジュール間の通信は通常、サービスを介して行われます。例えば、AuthServiceUsersService を呼び出してユーザーを検証できます:

auth/auth.service.ts
1
import { Injectable } from "@nestjs/common";
2
import { UsersService } from "../users/users.service";
3
4
@Injectable()
5
export class AuthService {
6
constructor(private readonly usersService: UsersService) {}
7
8
async validateUser(username: string, pass: string): Promise<any> {
9
const user = await this.usersService.findOne(username);
10
if (user && user.password === pass) {
11
return user;
12
}
13
return null;
14
}
15
}

複雑なプロジェクトにおけるモジュールの組織化と依存管理

複雑なプロジェクトでは、モジュールの組織化と依存管理が特に重要です。以下は、いくつかのベストプラクティスです:

フィーチャーモジュールを使用する

機能関連のコードをフィーチャーモジュールに整理します。例えば、ユーザー関連のすべてのコードを UsersModule に、製品関連のすべてのコードを ProductsModule に配置します。

共有モジュールを使用する

共通のサービス、パイプ、ガードなどを共有モジュールに配置し、必要な場所でインポートします。例えば、データベース接続やログサービスを提供する SharedModule を作成できます。

shared/shared.module.ts
1
import { Module } from "@nestjs/common";
2
import { DatabaseService } from "./database.service";
3
import { LoggerService } from "./logger.service";
4
5
@Module({
6
providers: [DatabaseService, LoggerService],
7
exports: [DatabaseService, LoggerService],
8
})
9
export class SharedModule {}
10
11
// app.module.ts
12
import { Module } from "@nestjs/common";
13
import { SharedModule } from "./shared/shared.module";
14
import { UsersModule } from "./users/users.module";
15
import { AuthModule } from "./auth/auth.module";
16
17
@Module({
18
imports: [SharedModule, UsersModule, AuthModule],
19
})
20
export class AppModule {}

モジュール間の依存性注入を使用する

依存性注入機構を使用して、モジュール間の緩い結合を確保します。例えば、サービスをモジュール内部で直接インスタンス化するのではなく、コンストラクタを通じて注入します。

products/products.service.ts
1
import { Injectable } from "@nestjs/common";
2
import { DatabaseService } from "../shared/database.service";
3
4
@Injectable()
5
export class ProductsService {
6
constructor(private readonly databaseService: DatabaseService) {}
7
8
async findAll(): Promise<any[]> {
9
return this.databaseService.query("SELECT * FROM products");
10
}
11
}

まとめ

この記事を通じて、NestJSでモジュールを作成および管理する方法について学び、モジュール間の依存関係と通信を探り、複雑なプロジェクトにおけるモジュールの組織化と依存管理を示すサンプルコードを提供しました。