NestJS
https://scrapbox.io/files/65128241e6449f001beade3c.svg
https://nestjs.com/
概要
Node.js 上で動作する サーバーサイドフレームワーク
TypeScript で実装されているため、TypeScript との相性が良い
JavaScript で記述することも可能
デフォルトで内部的に Express を用いるようになっているが、Fastly に変更することも可能
Under the hood, Nest makes use of robust HTTP Server frameworks like Express (the default) and optionally can be configured to use Fastify as well!
アーキテクチャは Angular に大きく影響を受けている
https://docs.nestjs.com/#philosophy
The architecture is heavily inspired by Angular.
NestJS#66de8c5e75d04f00002bd770
メリット
TypeScript を選択することで、型の恩恵を受け入れられる
Express の機能や豊富な関連ライブラリを利用できる
Nest CLI を用いることで、プロジェクトやファイルのテンプレートを作成できる
テスティングフレームワーク も標準で準備されている
様々な周辺ツールに対応しており、拡張性が高い
e.g. RDB, NoSQL, GraphQL, WebSocket ...
アーキテクチャ
以下の 3 つのコアとなる要素を用いて、1 つの機能を実装する
Module
Controller
GraphQL の場合は Resolver が該当
Service
処理フロー
https://zenn.dev/morinokami/articles/nestjs-overview
https://scrapbox.io/files/66e0454aa583b0001c585c50.png
Modules
https://docs.nestjs.com/modules
https://docs.nestjs.com/assets/Modules_1.png
関連する Controller や Service をまとめ、アプリケーションとして利用できるように NestJS に登録する
内部で必要となる外部モジュールをインポートしたり、外部にエクスポートしたりする
アプリケーションには必ず 1 つ以上の Root module と、0 個以上の Feature module が必要
Root module(app.module.ts): すべての Feature module を登録する Module
code:app.module.ts
@Module({
imports: CatsModule,
})
export class AppModule {}
Feature module: 各機能ごとの Module で、Controller や Service はここで登録する
code:cats/cats.module.ts
@Module({
controllers: CatsController,
providers: CatsService,
})
export class CatsModule {}
定義方法(ただし、nest g module コマンドで生成可能)
1. class に @Module デコレータを付与する
2. デコレータにプロパティを記述する
imports: モジュール内部で必要な外部モジュールを記述
exports: 外部にエクスポートしたいモジュールを記述
providers: @Resolver や @Injectable デコレータがついたクラスを記述
controllers: @Controller デコレータがついたクラスを記述
code:ts
@Module({
imports: PrismaModule,
providers: TaskResolver, TaskService
})
export class TaskModule {}
Controller
https://docs.nestjs.com/controllers
https://docs.nestjs.com/assets/Controllers_1.png
クライアントからのリクエストの受け取りとレスポンスの返却を担う
Service
https://docs.nestjs.com/providers
https://docs.nestjs.com/assets/Components_1.png
アプリケーション固有の ビジネスロジック を定義
Resolver / Controller から呼び出すことで、ユースケース を実現する
Resolver / Controller でビジネスロジックを記述しても良いが、責務ごとに分割することで 保守性・拡張性 を向上させる
単一責任の原則
定義方法(ただし、nest g service コマンドで生成可能)
1. class に @Injectable デコレータを用いる
2. ビジネスロジックを実現したメソッドを作成
code:ts
@Injectable()
export class UsersService() {
find(userName: string) {
// ...
}
}
Dependency Injection
https://docs.nestjs.com/fundamentals/custom-providers#di-fundamentals
NestJS は DI コンテナ を提供しているため、手動で DI する必要はない
方法
1. Module の providers に依存される側の(@Injectable が付与された)クラスを登録する
code:ts
@Module({
providers: TaskResolver, TaskService
})
export class TaskModule {}
2. 依存する側の コンストラクタ で、依存される側のクラスを引数として受け取る
code:ts
@Resolver()
export class TaskResolver {
constructor(private readonly taskService: TaskService) {}
// ...
}
CORS の設定
https://docs.nestjs.com/security/cors#getting-started
CORS を有効にするには、アプリケーションオブジェクトの enableCORS メソッドを呼び出す
code:main.ts
const app = await NestFactory.create(AppModule);
app.enableCors();
Prisma ORM
公式ドキュメントにも使用例が示されている
https://docs.nestjs.com/recipes/prisma
https://docs.nestjs.com/recipes/prisma#use-prisma-client-in-your-nestjs-services あたりの Service を生成する箇所から参考にすると良い radish-miyazaki.icon
code:src/prisma/prisma.service.ts
import { Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
async onModuleInit() {
await this.$connect();
}
}
code:src/prisma/prisma.module.ts
import { Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';
@Module({
providers: PrismaService,
exports: PrismaService,
})
export class PrismaModule {}
GraphQL
NestJS で GraphQL サーバを実装する
JWT
NestJS と Passport.js を組み合わせて JWT 認証を実現する
参考
NestJS × Reactで学ぶフルスタックGraphQLアプリケーション開発
#JavaScript #TypeScript