はじめに
株式会社ネクストスケープ ソリューションビジネス部の小野塚です。
この記事は「NEXTSCAPE Advent Calendar 2024」の17日目の記事となります。
色々ありましてNestJSを学び始めました。当社ブログでは扱われていなかったものの、既に様々なブログに取り上げられている言語ではございますが、実際に触ってみたところ、なかなか良さげな雰囲気もあり、そのアウトプットとして本記事を書いてみました。
NestJS はNode.jsをベースとしたサーバーサイドフレームワークであり、更にTypeScriptをフルサポートしています。
そのため、型安全なコードを書くことができ、更にモジュール構造や依存性の注入等の特徴を持っています。
このNestJSは2017年頃に発表され、Googleトレンドを見る限りでは2022年の初めにはNode.jsと同レベル、もしくはそれ以上の検索回数になっています。
Jestというテストフレームワークもデフォルトでサポートしており、ユニットテスト等も簡単に実施することができるということで、非常に良さげです。
まずは簡単な実行環境を作りつつ、その特徴を私なりに説明したいと思います。
準備
まず必要なものですが、先ほどお話しした通り、NestJSはNode.jsをベースとしていますのでNode.jsのインストールが必要です。
更にはnpmというパッケージマネージャ、つまり、必要なライブラリやツールをインストールしてくれるものが必要になりますが、npmはNode.jsに同梱されているのでNode.jsのみインストールすれば大丈夫です。
以下のURLから最新(LTS)のバージョンをダウンロード・インストールしてください。
この記事を書いている2024/12/8であればv22.12.0が最新です。
NestJSの基本構成
構成上このタイミングで基本構成を説明しますが、この後説明するサンプルプロジェクトの作成後、もう一度こちらを読んでもらうと良いかもしれません。
色々なNestJSの資料を読む限りでは以下の構成が一番わかりやすいかなと思います。
①main.ts:NestJSアプリケーションのエントリーポイント。ここから処理が始まります
②app.module.ts:NestJSアプリケーションのルートモジュールであり、アプリケーション全体の構成を定義するファイル。モジュールが追加される場合、ここに追加されます。
③~⑤:あとは各モジュールごとにモジュール、サービス、コントローラの3つで構成され、モジュールを追加するごとにこれらのファイルが作られます。
デフォルトで作成される「app.~.ts」もモジュール、サービス、コントローラの3つで構成されています
サービスはビジネスロジックを担当し、コントローラはクライアントからのリクエストを受け取ってサービスを呼び出し、レスポンスを返します。このように、サービスとコントローラは連携してアプリケーションの機能を実現します。
と、私を含むNestJS初心者の方々にはこのタイミングで書いても「なるほど」としか言えないと思いますので、繰り返しになりますが、以下のサンプルプロジェクトを作成し、動作確認を行ったところでもう一度読み返してみてください。恐らく納得いただけるのではと思います。
NestJS のマニュアルを見ると、あとはミドルウェア(Middleware)、デコレーター(Decorators)といったものも基本構成として挙げられてはいるのですが、まずはモジュール、サービス、コントローラの3つを押さえておくのがよいのではないでしょうか。
サンプルプロジェクトの作成
では、次に実際にサンプルプロジェクトを作成し、動作させてみましょう。
NestJSにおける「Hello World」です。
nestjstestというプロジェクトを作って、それをローカル環境とします
まずはプロジェクト作成。
「npm i -g @nestjs/cli」でNestJSのCLI(コマンドラインツール)をインストールします。
そして、プロジェクト作成のため、「nest new」の後にプロジェクト名を入力します。今回は「nestjstest」というプロジェクト名にします。
npm i -g @nestjs/cli
nest new nestjstest
パッケージを聞かれるのでnpmを選択します。
? Which package manager would you ❤️ to use? (Use arrow keys)
❯ npm
yarn
pnpm
しばらく進捗状況が作成された後に「Successfully created project nestjstest」というメッセージが表示されたら、プロジェクトが作成できたことになります。
そのプロジェクト直下のディレクトリに移動しましょう。
cd nestjstest
Swaggerのインストールのため、プロジェクトまで移動したら、ターミナルで以下コマンドを入力
npm install --save @nestjs/swagger
main.tsをテキストエディタで開くと以下のようになっています。
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();
最初のimport文に以下の行を追加して、
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
bootstrap()内のconst app~とawait app.listenの行の間に以下のコードを書き加えてください。
const config = new DocumentBuilder()
.setTitle('(APIのタイトルを入力)')
.setDescription('(APIの説明を記載')
.setVersion('1.0')
.addTag('(タグ名。省略可)')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document);
そして実行します。実行するときは以下のコマンドを叩いてください。
npm run start
特にエラーが出ないようであれば(入力待ちのような状態になるはず)、以下にアクセスしてみてください。
Swaggerの画面が表示されるはずです。
Swaggerでも確認はできますが、以下のURLを叩けば、
http://localhost:3000/
以下のように文字列が返される(ブラウザ上に表示される)はずです。
依存性の注入のサポート
先に書いた通り、NestJS では依存性注入(DI)の概念がフレームワークとして組み込まれています。
先ほどの流れでサンプルプロジェクトが作られましたのでこれを元に軽く説明しておきます。
まずはサービス部分、app.service.tsは以下のようになります。
「@Injectable()」と書かれた行、これは@Injectableデコレータというもので、このクラスがDIコンテナに登録されることを示しています。
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}
次にモジュール、app.module.tsが以下になります。
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
このようにproviders配列にAppServiceが含まれていることで、NestJSのDIコンテナにサービスが登録され、必要な場所で注入できるようになります。
実際にサービスを使用するコントローラー、app.controller.tsを見てみましょう。
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
}
本来コントローラー内で手動でサービスを作成しなければならないのですが、依存性の注入によりそれが不要となります。
Node.jsでも依存性の注入は可能なのですが、別途専用のモジュールをインストールする必要があり、NestJSのようにすぐに使えるというわけではありません。
テストフレームワークのサポート
「テストフレームワークのサポート」についても説明しておきます。
main.ts等が配置されているsrcディレクトリを見ると、通常のモジュールやサービスのファイル以外に「app.controller.spec.ts」というファイルがあります。この「~.spec.ts」というファイルがテスト用ファイルになりまして、以下の場合ですとコントローラ用のテストファイルが自動的に作成されていることになります。
ファイルの中身は以下のようになっておりまして、自動的に作成されたgetHolloを検証するコードが既に書かれています(見づらい方はブラウザで拡大してください。。すみません)。
言わずもがなかもですが、テストコードの内容が書かれているのはこれがサンプルであるためでして、自身が作成したコードに対しては当然自身でテスト処理を書く必要があります。
ちなみにCLIで独自のサービスやコントローラーを作成するとテストファイルも自動的に作成されますが、これはガワのみとなりますので中身を自分たちで書くことになります。
ガワだけであってもそうやってファイルを作成してくれると「テストコードを書かないといけないな」という気持ちにさせられます(私だけかもですが。。)。
テストを行うにはJestというJavaScriptのテストフレームワークが必要ですが、Node.jsのインストールで併せてインストールされているはずです。
実行するには対象のプロジェクト内で「rpm run test」を実行します。
すると配下の「~.spec.ts」ファイルに対してその中に書かれたテストプログラムを一通り実行します。
もし特定のファイルのみテストしたい場合は「npm run test」の後に「~.spec.ts」ファイル名を指定します。
今回は先ほど書いた通り既にテストコードが書かれているため、何も考えずにすぐに試すことができます。
その結果が以下になります(ディレクトリ名が違うのはご容赦を)。
無事「pass」していることがわかります。
Node.jsでもユニットテストは同じように行えるのですが、先に説明した依存性の注入により実際のオブジェクトの代わりにモックを注入したテストもできますので、より効率的に開発が進められます。
いかがでしょうか。結構至れり尽くせりなフレームワークかと思われます。
最後に(NestJSのデメリットも含)
以上、色々とNestJS万歳的な感じで書いてきましたが、当然デメリットもあります。色々言語仕様を知り尽くせばもっと出てくるかもですが、パッと思いつくのは以下のようなものです。
【学習コストの高さ】
NestJSを学ぶ前にTypeScriptやNode.jsの知識が必要になります
【情報が少ない】
まだ比較的新しめのフレームワークなので情報が、特に日本語の情報が少ないので学習がやや大変
【コミュニティがまだ小規模】
国内外でNestJSの普及や紹介をしてくれているところはあるのですが、これも上に書いた通り新しめ故に十分に情報が得られない可能性があります
とはいえ、非常に魅力的なフレームワークですので、特にNode.jsを知っている方々、そして型安全の言語を好む方にとってはおススメできます。
以上がNestJS についての簡単な説明・紹介となります。
正直なところ、このあたりはNestJS の基礎的な内容ですので知っている方には今更感満載の記事となりますが、実はこれに続きがありまして、NestJS をAzureリソース上で動かすために色々と試行錯誤した経緯を次回の私の記事で説明しようと思っております。
今回はその前準備、イントロ部分となります。
記事公開は恐らく来年になるかと思いますが、よろしくお願いいたします。
最後に。。
当社は新しい技術・知識を日々取り入れており、Webサイト、スマホアプリ、Hololensアプリの開発をはじめ、CMSを利用したサイトの新規構築やリニューアルなど、お客様のニーズに幅広く対応いたします。お困りのことがございましたら、いつでもお気軽にお問い合わせください。
(以下当社お問合せフォーム)