NODEJS用バックエンドフレームワークのNESTJS

NODEJS用バックエンドフレームワークのNESTJS

はじめに

Nest(NestJSともいう)とは、Node.jsを用いてサーバーサイドのアプリケーションを拡張可能かつ効果的に開発するために使われるフレームワークです。純粋なJavascriptとTypescriptを使ったものであり、以下の要素を組み合わせます。

  1. OOP(オブジェクト指向プログラミング)
  2. FP(関数型プログラミング)
  3. FRP(関数型リアクティブプログラミング)

NodeJSには様々なフレームワークがありますが、なぜNestJSを選んだ方が良いでしょうか。
GitHubの統計によると、2020年7月現在、GitHubでNestJSのお気に入り数が28,000を超えています。Web開発プログラミング言語として知られるJavaScriptが発展することにより、色々なJavascript、Nodejsのフレームワークが誕生しました。その中、NestJSがあります。NestJSも例外ではなく、バックエンド側のアプリケーションやRESTful APIを効果的かつ安易に作成することができます。

以下のstateofjs.comの2019年の調査結果どおりに、頻繁に使われているJavascriptのフレームワークについては、Express、Next.js、Koa、Meteor、Sails、Feathers、Nuxt、Gatsbyといった現在一番人気のあるフレームワークの他に、Nestはますます使われるフレームワークの一つでもあり、他のものよりトップになっています。

Credit: stateofjs.com

 

インストールおよび新たなNestJSアプリ作成

既にNode.js(10.13.0以上)がインストールされたことを確認しておいてください。

Nest CLIでは、簡単に新たなプロジェクトを設定することができます。インストールしておいたnpm をもっては、新たなプロジェクトを次のコマンドを実施して作成することができます。

$ npm i -g @nestjs/cli

nestjs-cliインストール

$ nest new project-name

新たなプロジェクト作成

上記のコマンドを実行したら、プロジェクトのディレクトリが生成され、NODEモジュールのライブラリやサンプルファイルがインストールされます。

プログラムを実行するために次のコマンドを使ってください。

npm start

その後、ブラウザにて http://localhost:3000にアクセスしたら、作成したアプリケーションが動いているのを確認できます。

構成およびExpressJSとFastifyの切替

NestJSがサポートできるHTTPプラットフォームが二つあります。ExpressFastifyです。

Express:Nodejsを使ったWeb開発コミュニティにおいて非常に人気があります。ExpressはNodeJS向けの、有名で簡単なWebフレームワークです。

Fastify:パフォーマンス面でより良いです。最大限の速度と生産性を提供することをコアとして高パフォーマンスで低コストのあるフレームワークです。

必要に応じて一つ選択してください。

デフォルトとしては、NestはExpressフレームワークを使います。

import './LoadEnv';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';
async function bootstrap() {
  try {
    const app = await NestFactory.create(AppModule);
    app.useGlobalPipes(new ValidationPipe());
    await app.listen(process.env.PORT || 3000);
  } catch (err) {
    console.log(err);
  }
}
bootstrap();

Fastifyを使ってNestJSを構成するため、最初に必要となるパッケージをインストールしておくべきです。

$ npm i --save @nestjs/platform-fastify

main.tsのbootstrap関数にて、Fastifyを利用するためパッケージをインポートし次のような構成をします。

const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter()
);

NestJSのルーティング

NestJSのルーティングは非常に定義しやすいです。 /usersのためのルーティングを定義するには、@Controller( ‘users’)修飾子を使用さえすればいいです。Post、Get、Put、Delete、Param、Bodyなどのルーティングについて該当するNestjsアノテーションさえ付ければいいです。
GET /users

GET /users/id

POST /users

@Controller(‘users’)修飾子に’users’のパスの接頭語を利用することで関連する各ルーティングをグループ化して同じコードを最低限に減少させることができます。

@Controller('users')
export class UsersController {
  @Get()
  find() {
    return this.usersService.find();
  }
  @Get(':id')
  findById(@Param('id') id) {
    return this.usersService.findById(id);
  }
  @Post()
  add(@Body() createUserDto: CreateUserDto) {
    return this.usersService.add(createUserDto);
  }
  @Patch(':id')
  update(@Param('id') id, @Body() updateUserDto: UpdateUserDto) {
    return this.usersService.update(id, updateUserDto);
  }
}

@Body ()修飾子を関数に入れることでリクエストオブジェクトがハンドラーにアクセスすることができます。

@Post()
 add(@Body() createUserDto: CreateUserDto) {
   return this.usersService.add(createUserDto);
}

@Param ()修飾子を用いることでメソッドのパラメーターにアクセスすることができます。以下の例を見てください。idのパラメーターにアクセスするため、@Param(‘id’)をコールするだけでよいです。

@Get(':id')
  findById(@Param('id') id) {
    return this.usersService.findById(id);
}

NestJSの概念

Providers: Providers(プロバイダ)とはNestの基本概念です。基本的なNestクラスの多くはservices、repositories、factories、helpers等のプロバイダとして扱われます。プロバイダのアイデアは依存関係を注入できることです。これはオブジェクトが互いにさまざまな関係を作成できることを意味し、オブジェクトのインスタンスを「繋げる」機能はNestランタイムシステムに委任できます。プロバイダは単に@Injectable()修飾子が付けられたクラスです。

まずは、簡単なサービスを作成してみましょう。UsersService のサービスはデータの保存と取得を担当し、UsersControllerで使用されるように設計されます。そのため、これらのクラスが関係になるようなプロバイダを作成すべきです。

 

@Injectable()
export class UsersService {
  constructor(
    @InjectRepository(User)
    private usersRepository: Repository<User>,
  ) {}
  async findOne(username: string): Promise<User | undefined> {
    return this.usersRepository.findOne({ name: username, deleted: 0 });
  }
  async find(option?: FindManyOptions<User>): Promise<User[]> {
    return this.usersRepository.find(option);
  }
  async findById(id: number): Promise<User> {
    return this.usersRepository.findOne(id);
  }
  async add(user: CreateUserDto): Promise<User> {
    return this.usersRepository.save(user);
  }
  async update(user: UpdateUserDto): Promise<User> {
    return this.usersRepository.save(user);
  }
}

HINT:CLI(nest g service catsコマンド)を用いることでサービスを作成できます。
@Injectable修飾子()はNestがこれがプロバイダーであるということを知らせるのを手助けします。そのため、Nestは自動的にこのクラスのインスタンスを作成し、UserControllerにそれを渡します。

Modules:Modules(モジュール)は@Module()修飾子が付けられたクラスです。@Module()修飾子はアプリケーション構造をNestが整理するために使うメタデータを提供します。

アプリケーション毎には少なくとも一つのモジュール、ルートモジュールがあります。モジュールはアプリケーションのコンポーネントまたは性能を象徴します。コンポーネントを整理する効果的な方法としてモジュール化がおすすめです。ソースの構成は以下のようになります。

GraphQL

周知の通りに、GraphQL とは既存データ抽出とデータロードに使われるAPI向けのグラフクエリ言語です。Nestを使って安定なGraphQLサーバーを構築できます。

GraphQLについての基礎知識を持っていることを前提とし、NestでのGraphQLの使い方を調べてみましょう。

必要なパッケージを予めインストールしておきます。

npm i --save @nestjs/graphql apollo-server-express graphql-tools graphql type-graphql

お使いのプラットフォームがExpressかFastifyであるかによって、apollo-server-expressまたはapollo-server-fastifyをインストールしなければなりません。

おすすめのGraphQLの主な概念は以下の通りとなります。

  1. Schema
  2. Query
  3. Mutation
  4. Type
  5. Resolver

NestJSは、GraphQLアプリケーションを構築するために以下のような二つの方法を提供します。

  1. Schema first
  2. Code first

まとめ

前述した通りに、NestJSはたくさんの様々な役立つ機能でサーバサイドのアプリケーションを安易に構築できるように開発者をサポートしてくれます。幾つかのデメリットがありますが、力強さと便利さは選択肢から外せないものです。以下に、そのメリットとデメリットを示します。

 

メリット

オープンソース

多くのユーザビリティがあり、強いフレームワーク

分かりやすいドキュメント

速やかな開発可能

バックエンド開発のためのAngularスタイルの構成

Node.jsのエコシステム

Graphqlのサポートが容易

良いアーキテクチャ

VSCodeでTypescriptがうまく統合している

 

デメリット

ユーザーの利用数が少なくて、Stackoverflowでの該当記事が少ない

致命的な影響があるアップデート

安定性なし

デバッグしにくい

参照元

https://expressjs.com/

https://www.fastify.io/

https://docs.nestjs.com/graphql/quick-start

https://docs.nestjs.com/techniques/performance

https://docs.nestjs.com/fundamentals/execution-context#reflection-and-metadata

https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841

https://www.apollographql.com/blog/graphql-vs-rest-5d425123e34b/