More Related Content
Similar to TypeScript製フレームワーク「Nest」のご紹介
Similar to TypeScript製フレームワーク「Nest」のご紹介 (20)
More from bitbank, Inc. Tokyo, Japan
More from bitbank, Inc. Tokyo, Japan (20)
TypeScript製フレームワーク「Nest」のご紹介
- 2. Copyright © bitbank, inc.
自己紹介
❏ ビットバンクでサーバーサイドを担当
❏ Node.js, TypeScript
❏ 前職ではモバイルゲームを開発
❏ C++, C#, PHP, etc.
Daiki Yokoi
- 3. Copyright © bitbank, inc.
目的とアジェンダ
Nestについて広く浅く紹介し、興味を持ってもらう
❏ Nestを使い始めるまで
❏ そもそもどんな課題があったのか
❏ Nest入門
❏ 前提となる基礎知識をつける
❏ Nestの機能紹介
❏ どのようなことができるのか
- 5. Copyright © bitbank, inc.
❏ 既存のアプリは Node.js (v6) + Express という構成
❏ コードの透明性と柔軟性が高い
❏ データ構造がわかりにくく、可読性が低い
❏ フロントエンドチームの知見も借りられる
❏ TypeScript + Angular で開発している
Nestを使い始めるまで
新規開発はTypeScriptでやりたい
- 6. Copyright © bitbank, inc.
Nestを使い始めるまで
TypeScript化と同時により効率的な開発手法を模索
❏ DIの導入
❏ ユニットテストの効率化など
❏ ルーティング効率化
❏ ハンドラの登録をよりモダンな形で行えないか
❏ APIドキュメント
❏ スプレッドシートでの手動管理から脱却
❏ 自動でSwaggerUIに繋ぎこみたい
- 7. Copyright © bitbank, inc.
❏ InversifyJS [1]
❏ IoCコンテナ
❏ routing-controllers [2]
❏ デコレータでハンドラを登録できる
❏ tsoa [3]
❏ APIドキュメントの自動生成
[1] http://inversify.io/
[2] https://github.com/typestack/routing-controllers
[3] https://github.com/lukeautry/tsoa
Nestを使い始めるまで
いくつかのツールを試してみた
- 8. Copyright © bitbank, inc.
Nestを使い始めるまで
これらが統合されたフレームワークが欲しくなった
❏ 各ツールの守備範囲が微妙に噛み合わない
❏ ツールごとの前提条件や制約もあり、まとめ上げるのが少し面倒
- 10. Copyright © bitbank, inc.
Nestを使い始めるまで
Nestを使ってみることに
❏ もともと欲しかった機能が一通り揃っていた
❏ オリジナルのDIコンテナ
❏ デコレータでのハンドラ登録
❏ APIドキュメントの生成
❏ ポピュラーになりそう
❏ 日本語情報が全くない中、GitHubのスターは5000超え (2018/03時点)
❏ Angularのカンファレンスにも登場
- 12. Copyright © bitbank, inc.
Nest入門
❏ 簡単に言うとクラスの集まり
❏ 例)UserModule = UserController + UserService + …
❏ 関係性の強いクラスでまとめるべき
❏ 複数のモジュールがツリー状になって一つのアプリを構成
❏ 頂点のモジュールは ApplicationModule と命名されるのが一般的
フレームワーク独自のモジュールという概念がある
- 14. Copyright © bitbank, inc.
Nest入門
❏ コントローラー
❏ 各エンドポイントへのリクエストハンドラを持つクラス
❏ プロバイダ
❏ コントローラー以外のクラス
❏ ロジックを持ち、コントローラーや別のプロバイダから呼び出される
モジュール内の各クラスは以下の2つに分類される
- 15. Copyright © bitbank, inc.
Nest入門
コントローラーではデコレータでハンドラを登録する
@Controller(‘users’)
class UserController {
@Get(‘:id’)
create(@Param(‘id’) id: string) {
// GET /users/1 等をハンドリングする
}
@Post()
create(@Body() body: CreateUserRequest) {
// POST /users をハンドリングする
}
}
- 16. Copyright © bitbank, inc.
Nest入門
プロバイダは各種ビジネスロジックを担当
UserModule
UserController UserService
UserDetailService
SessionService
Controllers Providers
- 17. Copyright © bitbank, inc.
Nest入門
依存関係はコンストラクタの実装を元に解決される
@Controller(‘users’)
class UserController {
constructor(private readonly userService: UserService) {}
// 略
}
---
@Injectable()
class UserService {
constructor(private readonly userDetailService: UserDetailService) {}
// 略
}
---
class UserDetailService {
- 18. Copyright © bitbank, inc.
Nest入門
❏ ツリー状のモジュール群がアプリケーションを構成
❏ トップのモジュールは Application Module と命名する
❏ モジュールは関係性の強いクラスの集合
❏ コントローラークラス => リクエストハンドラ
❏ プロバイダクラス => ビジネスロジック
❏ クラス間の依存関係はコンストラクタの実装を元に解決される
❏ モジュールをまたぐクラス間の依存関係の解決手段もある
ここまでのおさらい
- 19. Copyright © bitbank, inc.
@Module({
imports: [UserModule]
})
export class ApplicationModule {}
---
import { NestFactory } from '@nestjs/core';
import { ApplicationModule } from './app.module.ts';
async function bootstrap() {
const app = await NestFactory.create(ApplicationModule);
await app.listen(3000);
}
bootstrap();
Nest入門
モジュールが作成できたらサーバーを起動できる
ツリーのトップのモジュールを渡す
- 21. Copyright © bitbank, inc.
❏ コントローラの実装を解析してドキュメントを生成する
❏ 必要に応じてデコレータで追加の情報を与えられる
APIドキュメントを自動で作成し、SwaggerUIに連携
Nestの機能紹介
- 22. Copyright © bitbank, inc.
Nestの機能紹介
ロギングやレスポンスの整形に便利なインターセプタ
❏ ハンドラの実行前後に処理を差し込むことができる
❏ リクエスト開始時と終了時のログを簡単に紐づけることができる
❏ レスポンスにメタデータを追加したりするのにも便利
❏ いわゆるアスペクト指向プログラミングをサポートしてくれる
- 23. Copyright © bitbank, inc.
@Injectable()
export class LoggingInterceptor implements NestInterceptor {
intercept(contexct: ExecutionContext, call$: Observable<any>): Observable<any> {
const requestId = uuid.v4();
console.log(`[Before] requestId: ${requestId}`);
return call$.pipe(
tap(() =>
console.log(`[After] requestId: ${requestId}`)
),
);
}
}
Nestの機能紹介
ロギングやレスポンスの整形に便利なインターセプタ
一つのメソッド内で
前後の処理を記述できる
- 24. Copyright © bitbank, inc.
Nestの機能紹介
リクエストパラメータと同時に定義するバリデーション
class CreateUserRequest {
@Length(10, 100)
@IsEmail()
readonly mail!: string;
}
@Controller(‘users’)
class UserController {
@Post()
create(@Body() body: CreateUserRequest) {
// 新規ユーザーを作成
}
}
この時点では以下が全て完了している
- リクエストボティのパース
- 指定したクラスへの変換
- バリデーションの実行
各バリデーションをデコレータで定義
- class-validatorが提供するもの
- カスタマイズも可能
- 25. Copyright © bitbank, inc.
Nestの機能紹介
Passportでの認証もサポート
❏ Passportはポピュラーな認証ツール
❏ JWT (JSON Web Token) やSAMLなど多様な認証手法が実装されている
❏ @nestjs/passportという公式パッケージがある
❏ 認証部分をアスペクト指向で実装する枠組みを提供してくれる
- 26. Copyright © bitbank, inc.
Nestの機能紹介
ガードによってアクセスコントロールを実現
❏ ガードは不正なリクエストを弾くための仕組み
❏ canActivateというインターフェースが用意されている
❏ リクエストデータを受けてboolean値を返すメソッドを実装するだけ
❏ 登録されたハンドラの実行前に評価される
❏ ビットバンクのあるアプリケーションではAPIごとに権限を設定
❏ Nestの全モジュールをスキャンしてAPI一覧を取得
❏ これを各ユーザーに割り当てる
❏ あとはガードの中でユーザーの権限をチェックすれば良い
- 27. Copyright © bitbank, inc.
❏ TypeORMはポピュラーな O/R Mapper
❏ 基本的なユースケースはほぼカバーされている印象
❏ トランザクションやパーティショニングが絡むと少しだけ手間だが問題ない範囲
❏ どうにもならなければSQLを直接書くこともできるがあまり使わない
❏ マイグレーションの仕組みも用意されている
❏ メンテナーの方が非常にオープンかつ反応が早い
❏ IssueやPRがすぐ処理される安心感
❏ @nestjs/typeorm という公式パッケージがある
❏ TypeORMのリポジトリクラス等を他のクラスと同じように簡単にDIできる
Nestの機能紹介
TypeORMでのデータベースアクセスをサポート
- 28. Copyright © bitbank, inc.
モックを使用したテストを簡単に行える
Nestの機能紹介
❏ @nestjs/testing という公式パッケージがある
❏ モジュール内の一部のクラスをモックに差し替えることができる
❏ 依存先が多いクラスをテストする際に便利
❏ ユニットテストにもe2eテストにも使える
❏ 特定のテストフレームワークとの連携はなし
❏ サンプルではJestというFacebookが開発するツールが使用されている
❏ JestはテストAPIやモック化の手法が豊富で使いやすい
❏ カバレッジを計測してHTMLで出力することもできる
❏ ビットバンクではMochaからJestへの移行が進んでいる
- 29. Copyright © bitbank, inc.
その他
Nestの機能紹介
❏ CLIツール
❏ @nestjs/cli という公式パッケージがある
❏ nest new <app-name> でアプリケーションの雛形ができる
❏ 個別のコンポーネントを作成することもできる
❏ コントローラー部分はREST以外にも対応可能
❏ GraphQL, WebSocket, gRPC, etc.
❏ MVCにも対応可能
- 30. Copyright © bitbank, inc.
❏ TypeScriptで開発したい方
❏ Nestで本格的なアプリケーションを作ってみたい方
❏ 暗号通貨取引所のバックエンドを支えたい方
最後に
仲間を募集しています :)