【Node.js】TypeScript製Node.jsフルスタックフレームワーク Nest 導入編

node_js_framework_nest

NestはNode.jsのフルスタックフレームワークです。Angularから非常に強い影響を受けており、TypeScriptで構築されています。

Nestドキュメント

TestableでScalableで疎結合でメンテナンスしやすいアプリを少ない労力で開発できること。また、他のNode.jsライブラリを苦労なく組み込んで使えることを目指して開発されているようです。メインの開発者はScal.ioKamil Myśliwiec氏であり、Scal.io含めvalor-softwareなど幾つかの会社がスポンサーとなってMITライセンスで開発されています。

Nest is a framework for building efficient, scalable Node.js server-side applications.

🐯NestのインストールとHello World

nestjsの動作要件としてNode.js v6.11.0 が必要です。 公式でNestのスターターキットがgithub上に用意されているので、これを使ってみましょう。

Nest v.4.5で動作させています。

git clone https://github.com/nestjs/typescript-starter.git project
cd project
npm install 
npm run start:dev

http://localhost:3000 を開きます。

次はスターターキットのコードを見ていきます。Angularをやっている方には解りやすい構成と思います。

  • app.controller.spec.ts
  • app.controller.ts
  • app.module.ts
  • main.ts

main.tsがエントリーポイントです。

/* 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();

AppModuleをNestFactory.create()に渡しています。 下記が app.module.ts です。使用するcontrollerやcomponentsを配列の中で宣言します。

/* app.module.ts */

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';

@Module({
  imports: [],
  controllers: [AppController],
  components: [],
})
export class AppModule {}

下記がデフォルトでAppModuleに組み込まれているAppControllerです。 @Get()や@Post(), @Delete(), @Put()などのデコレーターでルートを宣言します。 デフォルトでは '/' にGetメソッドでアクセスされた時の root() だけ定義してあります。 http://localhost:3000 にブラウザアクセスすると 'Hello World' という文字列が返ってきます。

import { Get, Controller } from '@nestjs/common';

@Controller()
export class AppController {
  @Get()
  root(): string {
    return 'Hello World!';
  }
}

🥥 Controller

Controller

コントローラーの責務はリクエストを受け取り、レスポンスを返すことです。コントローラーの宣言はデコレーター (metadata) で行います。

@Controllerデコレーターの中身でrouteが決まります。すなわち、@Controller('foods')で http://localhost:3000/foods へのルーティングが定義されます。@Getの後ろに定義した関数 (下記ではfindAll) でリクエストをハンドルして、レスポンスを返します。

http://localhost:3000/foods にアクセスすると、['omochi', 'nattou', 'tofu', 'soba', 'udon']が返ってきます。

/* foods.controller.ts */

import { Controller, Get, Post, Put, Delete, Res} from '@nestjs/common';

@Controller('foods')
export class FoodsController {
    @Get()
    findAll() {
        return ['omochi', 'nattou', 'tofu', 'soba', 'udon'];
    }
    @Post()
    create(@Res() res) {
        res.send('post!');
    }
    @Put()
    update(@Res() res) {
        res.send('put!');
    }
    @Delete()
    delete(@Res() res) {
        res.send('delete!');
    }
}

パラメーターを受け取る

下記のようにしてパラメーターを受け取ることができます。

http://localhost:3000/hello/bbbb などでアクセスすると {"id":"bbbb"} が返されます。

/* app.controller.ts */

import { Get, Controller, Param } from '@nestjs/common';

@Controller('hello')
export class AppController {
  @Get(':id')
  hello(@Param() param): string {
    return param;
  }
}

🌰 Component

Component

上でコントローラーを見ましたが、コントローラーの責務はHTTPリクエストをハンドリングして、レスポンスを返すことにあり、より複雑なロジックはComponentに移譲する設計になっています。 Angularと少し違うのですが、Componentという概念にはServiceやRepository, Factory, Helperなどが含まれます。それらをControllerや他のComponentにDI (依存性注入) することができます。

/* foods.service.ts */

import { Component } from '@nestjs/common';

@Component()
export class FoodsService {
    private readonly washoku: string[] = ['unadon', 'katsudon', 'oyakodon', 'wasabidon', 'kakunidon'];
    getDonburi() {
        return this.washoku;
    }
}

ここはAngularと同じでDIに使用するServiceはModuleのComponentsで宣言する必要があります。

/* app.module.ts */

import {FoodsService} from './foods.service';

...
@Module({
  imports: [],
  controllers: [AppController, FoodsController],
  components: [FoodsService],
})
export class AppModule {}

Controllerです。ControllerもAngularと同じでConstructorでインスタンスを宣言して、DIします。

/* foods.controller.ts */

import {Controller, Get} from '@nestjs/common';
import {FoodsService} from './foods.service';

@Controller('foods')
export class FoodsController {

    /* FoodsServiceをDI */
    constructor(private readonly foodsService: FoodsService) {}

    @Get()
    findAll() {
        /* FoodsServiceのメソッドを呼び出す */
        return this.foodsService.getDonburi();
    }
}

今回はここまでとなりますが、また機会を見て、またNestのModelやMiddlewaresなどの機能を紹介しようと思います。読んでいただき、ありがとうございました。

🍙 参照

  • このエントリーをはてなブックマークに追加