1最小の機能モジュール
コントローラとサービスを1つの機能単位に束ねる最小のモジュールです。@Module() のオブジェクトが「この機能の部品一覧表」になっており、登録した部品の間でだけ注入が解決されます。
import { Module } from "@nestjs/common";
import { UsersController } from "./users.controller";
import { UsersService } from "./users.service";
@Module({
controllers: [UsersController], // HTTP の受付係を登録
providers: [UsersService], // 注入可能なクラスを登録
})
export class UsersModule {}
// このファイルが「users 機能の部品一覧表」になる
2ルートモジュールへの登録
作った機能モジュールを AppModule の imports にぶら下げる例です。main.ts → AppModule → 機能モジュールという木構造でアプリが組み上がる、という全体の骨組みを示します。
import { Module } from "@nestjs/common";
import { UsersModule } from "./users/users.module";
@Module({
imports: [UsersModule], // 機能モジュールをぶら下げる
})
export class AppModule {}
// アプリは木構造で組み上がる
// main.ts → AppModule → UsersModule → (Controller / Service)
// NestFactory.create(AppModule) はこの木を根からたどって組み立てる
3機能追加の定型手順
「注文機能を追加して」と言われたときの実務の定型手順です。フォルダを作って部品を揃え、AppModule の imports に1行足すだけで機能が増える、という増築のリズムを体感する例です。
import { Module } from "@nestjs/common";
import { UsersModule } from "./users/users.module";
import { OrdersModule } from "./orders/orders.module";
// 新機能「注文」を追加する手順:
// ① src/orders/ に controller / service / module の3点を作る
// ② OrdersModule の controllers / providers にその2つを登録
// ③ AppModule の imports に1行足す(↓これだけ)
@Module({
imports: [UsersModule, OrdersModule],
})
export class AppModule {}
4登録忘れエラーの読み方
providers への登録忘れで起きる Nest can't resolve dependencies エラーの読み解き方です。エラーメッセージ中の (?) が解決できなかった依存の位置を表すと知っていれば、実務のデバッグが一気に速くなります。
import { Module } from "@nestjs/common";
import { UsersController } from "./users.controller";
import { UsersService } from "./users.service";
// UsersService を providers に書き忘れると、起動時にこうなる:
//
// Nest can't resolve dependencies of the UsersController (?).
// Please make sure that the argument UsersService at index [0]
// is available in the UsersModule context.
//
// (?) = コンストラクタの 0 番目の引数が解決できなかった、の意味
@Module({
controllers: [UsersController],
providers: [UsersService], // ← この1行の書き忘れが原因
})
export class UsersModule {}
5実務アプリのモジュール構成
認証・ユーザー・注文・決済を持つ実務規模アプリの AppModule です。imports の一覧がそのまま「アプリの機能一覧」として読めるため、初めて触るコードベースでも AppModule から全体像を掴むのが定石です。
import { Module } from "@nestjs/common";
import { AuthModule } from "./auth/auth.module";
import { UsersModule } from "./users/users.module";
import { OrdersModule } from "./orders/orders.module";
import { PaymentsModule } from "./payments/payments.module";
@Module({
imports: [AuthModule, UsersModule, OrdersModule, PaymentsModule],
})
export class AppModule {}
// AppModule
// ├─ AuthModule … ログイン・トークン発行
// ├─ UsersModule … ユーザー管理
// ├─ OrdersModule … 注文
// └─ PaymentsModule … 決済
// imports がそのまま「機能一覧の目次」として読める