やりたいこと バリデーションの方法 手順 1. 必要なライブラリをインストール 2. バリデーション定義ファイルを作成する 3. app.module.tsにバリデーション関数を追加する 4. 使い方
やりたいこと
- 環境変数が未設定のときにエラーを出したい
- コード内で環境変数を扱うときに型推論が活かされるようにしたい
バリデーションの方法
Documentation | NestJS - A progressive Node.js framework
バリデーションの実装方針は大体3通りほど存在する。
- joiを使う(公式ドキュメントに記載あり)
- class-validatorを使う(公式ドキュメントに記載あり)
- zodを使う(公式ドキュメントには記載なしだが、一般的なスキーマ定義方法としてよく知られている)
今回は、型定義とバリデーションが一元管理でき、設定も複雑にならないclass-validatorを使った方法を紹介する。
手順
1. 必要なライブラリをインストール
pnpm add @nestjs/config class-validator class-transformer
2. バリデーション定義ファイルを作成する
ほぼ公式ドキュメント通りに書く。
今回は3種類の環境変数を定義。
-
NODE_ENV
:development
orproduction
を取りうる -
TZ
:日本時間固定 -
DATABASE_URL
:PostgreSQLに接続するためのURL
// env.validation.ts
import { plainToInstance } from 'class-transformer';
import { IsEnum, IsString, validateSync } from 'class-validator';
enum Environment {
Development = 'development',
Production = 'production',
}
export class EnvironmentVariables {
@IsEnum(Environment)
NODE_ENV: Environment;
@IsString()
TZ = 'Asia/Tokyo';
@IsString()
DATABASE_URL: string;
}
export function validate(config: Record<string, unknown>) {
const validatedConfig = plainToInstance(EnvironmentVariables, config, {
enableImplicitConversion: true,
});
const errors = validateSync(validatedConfig, {
skipMissingProperties: false,
});
if (errors.length > 0) {
throw new Error(errors.toString());
}
return validatedConfig;
}
3. app.module.tsにバリデーション関数を追加する
ConfigModule.forRoot()
の関数の中に、先程作成した関数を設定する。
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from '@nestjs/config';
import { validate } from './env.validaton';
@Module({
imports: [
ConfigModule.forRoot({
validate: validate,
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
4. 使い方
コード内で環境変数を呼び出すには、以下のように実装する。
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { EnvironmentVariables } from './env.validaton';
@Injectable()
export class AppService implements OnApplicationShutdown {
constructor(
private readonly configService: ConfigService<EnvironmentVariables>, // ここで型定義したものを入れる
) {}
getHello(): string {
const envName = this.configService.get('NODE_ENV', { infer: true }); // infer: trueで推論を有効化する
return `Hello World! env=${envName}`;
}
}