🀄

初心者向けNestJS(Typescript)バックエンド開発講座

2022/05/02に公開

はじめに

NestJS、何それおいしいの?って方が、NestJSでバックエンドを開発することを通して、理解を深めます。
TypeScriptと呼ばれるプログラミング言語を使って、簡単な実装をします。

そもそもバックエンドとは何か

フロントエンドは、ユーザには見える画面といった機能を指すイメージです。
一方、バックエンドは、ユーザには見えない機能を指すイメージです。
例えば、データベースからデータを取得・登録・削除するといった処理は、ユーザには見えないので、バックエンドの機能となります。
一方、取得したデータを画面に表示するといった処理はフロントエンドの機能です。

バックエンドエンジニアとは

バックエンドエンジニアとは、一体何者なんでしょうか。こちらをご覧ください

バックエンドエンジニアのロードマップの例です。
ネットワークから始まり、プログラミングやデータベース、セキュリティなど幅広い知見が必要となります。

こちらは海外企業の役職レベル別の年収レンジが確認できるサイトです。
世界トップレベルのバックエンドエンジニアの給与って半端ないっすね…

NestJSとは

NestJS公式ドキュメントを引用します。

Nest (NestJS) is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with and fully supports TypeScript (yet still enables developers to code in pure JavaScript) and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).

初学者向けにわかりやすく言い換えると、
NestJSは、Typescriptでバックエンドのプログラムを非常に効率良く開発できるもの
というイメージです。

NestJSの開発環境を準備する

NestJSを利用するためには、Node.jsがPCにインストールされている必要があります。
すなはち、ターミナルでnode -vと叩くとバージョンが表示されることが必要です。
もしNode.jsをインストールすることでPC環境を汚したくない方は、こちらのWEBサービスを活用しましょう。

NestJSの新規プロジェクトを作る

公式ドキュメントの通りにセットアップを進めていきます。
まず、npmとは「Node Package Manager」の略称です。
世界中で作成されたモジュール(部品化したプログラム)を誰もが再利用できるようにしたものです。

ターミナル
npm i -g @nestjs/cli
nest new test-project #project-nameは自分で命名する。
# 今回npmを選択する

以下、npmコマンドを叩く様子。
image.png

以下、nestコマンドを叩く様子。
image.png

以下、インストールが正常に完了すると以下が表示される。
image.png

以下、ディレクトリおよびファイルが生成されていることを確認。
image.png

まずはプログラムを動かしてみる

以下コマンドを実行します。

ターミナル
cd test-project # ディレクトリを移動
npm run start:dev # 開発モードで実行

ブラウザを開き、http://localhost:3000/ にアクセスします。以下のようにHello World!と文字列が返ってきます。
image.png

ソースコードを見る

プロジェクトを新規作成されるとデフォルトでサンプルの機能が実装されています。
まず、src配下のapp.service.tsを開きます。
getHello()と呼ばれるHello World!という文字列を返す関数が存在することが確認できます。

image.png

次にapp.controller.tsを開きます。
こちらはクライアントがアクセスしたURLに従って、サービスクラスの関数を呼び出しています。

image.png

このようにNestJSでは、サービスコントローラーなど、プログラムの責務を明確に分離することになります。
責務を分離するため、プログラムを変更した際の影響範囲を極小化することができます。
またNestJSでは、DI(Dependency Injection)と呼ばれるデザインパターンが使われます。
ここでは説明を割愛しますが、このDIによって、プログラムを疎結合にして依存性をなくすことができるため、テスト駆動開発が可能になるなどの多くのメリットを享受できます。

NestJSを理解する

こちらは公式ドキュメントから抜粋したNestJSを構成する要素です。

  • Controller
  • Provider
  • Module
  • Middleware
  • Exceptiopn filters
  • Pipes
  • Guard
  • Interceptors
  • Custom decorator

今回利用する以下3つの要素について簡単に説明しておきます。

  • Controller:クライアントからのリクエストを受けて、レスポンスを行う。
  • Provider:ビジネスロジックなどを提供する。
  • Module:部品化することで、再利用できるようにする。

詳しくは公式ドキュメントを一読ください。

新しくバックエンドの機能をつくる

新たなバックエンドの機能を追加します。
今回は、ユーザ情報を登録・取得する機能を作ってみます。
nest gnest genarateのショートカットコマンドです。
以下のコマンドを叩くことで機能のベースをつくります。

ターミナル
cd test-project
nest g module users
nest g controller users --no-spec # テストファイルをつくらないおまじない
nest g service users --no-spec # テストファイルをつくらないおまじない

新しくディレクトリおよびファイルが生成されたのを確認します。

image.png

Modelを実装する

※本来はData Transfer Object (DTO)と呼ばれるデザインパターンで実装するのが一般的ですが、今回は初心者向けのため割愛します。

ユーザ情報のデータモデルをつくります。
と、その前にClass validatorと呼ばれるバリデータ用ライブラリを導入します。
導入方法は公式ドキュメントに従います。
バリデータとは、簡単に言うと「文字列であること」や「何文字以上であること」など、データ属性を保証するために使うものです。

image.png

ターミナル
# バリデータ用ライブラリを導入する
npm i --save class-validator class-transformer

# ユーザ情報のデータモデル(空のファイル)を作成する
touch src/users/user.ts

src/users/users.ts
import { IsString, MinLength, MaxLength } from 'class-validator';
export class User {
    @IsString()
    @MinLength(1)
    @MaxLength(20)
    readonly name: string;

    @IsString()
    @MinLength(6)
    @MaxLength(20)
    readonly password: string;
}

Serviceを実装する

src/users/users.service.ts
import { Injectable } from '@nestjs/common';
import { User } from './user';

@Injectable()
export class UsersService {

    users: User[] = [];

    create(user: User) {
        this.users.push(user)
    }

    findAll() {
        return this.users
    }
}

Controllerを実装する

src/users/users.controller.ts

import { Body, Controller, Get, Post, ValidationPipe } from '@nestjs/common';
import { User } from './user';
import { UsersService } from './users.service';

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Get()
  findAll() {
    return this.usersService.findAll();
  }
  @Post()
  create(@Body(ValidationPipe) user: User) {
    return this.usersService.create(user);
  }

}

実装したものを動かしてみる

ターミナル
npm run start:dev
ターミナル

# 空のユーザー情報がレスポンスされる
curl http://localhost:3000/users

# ユーザ情報をPOST
curl -X POST -H "Content-Type: application/json" -d '{"name":"John","password":"1234567"}' http://localhost:3000/users 

# 先程のPOSTしたユーザ情報がレスポンス
curl http://localhost:3000/users 

ユーザ情報がレスポンスされる様子
image.png

おわりに

実際の開発では、フロントエンドやデータベースなどの機能との連携が必要になってきます。
今回は、NestJSで簡単なバックエンドの機能をつくることで、NestJSの理解を深めることを目的に執筆しました。

以上です

Discussion