😺
Nest.js におけるモジュール/サービス
Module のデコレータ
import { Module } from '@nestjs/common';
import {SendgridService} from "./sendgrid.service";
@Module({
// モジュール定義をこちらに
})
export class HogeModule {
}
-
providers
モジュール内で有効化するサービスを定義します。 -
controllers
モジュール内で有効化する コントローラを定義します。 -
imports
読み込む外部のモジュールを定義します。 -
exports
モジュールとして読み込まれた際に公開する サービスを定義します。
Angular のモジュールでは export を利用してコンポーネントやディレクティブの公開を行っていましたが、
nest.js における imports / exports は、主に Service の受け渡しをする目的で利用されます。
Service の Provider Scope
Nest.js には Angular のような injectedIn: "root"
のような Provider Scope が存在せず、
すべてのモジュールは、モジュールの範囲でシングルトンで管理されます。
サーバサイドのスコープは、nest start でサーバを立ち上げたタイミングで処理され、
その後の各リクエスト内で同じオブジェクトが使い回されるため、
PHP などの shared nothing な バックエンド開発に慣れている人には注意が必要です。
Nest.js では、以下 3種の Scope が用意されています。
-
DEFAULT
: オブジェクトはアプリケーション全体でシングルトンで管理されます。 -
REQUEST
: オブジェクトはリクエストのたびに再生成され、破棄されます。 -
TRANSIENT
: オブジェクトはユーザごとに生成され、同じユーザに同じオブジェクトが維持されます。
これらの Scope は以下のように injectable デコレータで定義することが可能です。
import { Injectable, Scope } from '@nestjs/common';
@Injectable({ scope: Scope.REQUEST })
export class CatsService {}
Controller ももちろん DI で管理されるオブジェクトです。
Controller の場合には、 controller ディレクティブ内で、 scope 値を利用して Scope を定義できます。
@Controller({
path: 'cats',
scope: Scope.REQUEST,
})
export class CatsController {}
Scope の階層化
Scope はの仕組みは、依存チェーンの中でバブリングします。
例えば、CatsController <- CatsService <- CatsRepository
のような依存グラフがあり、
CatsService が RequestScope の場合、CatsController
も RequestScope になります。
参考
Discussion