Slide 1

Slide 1 text

/FTU+4º5ZQF03. @tascript Fukuoka.ts

Slide 2

Slide 2 text

;͋Έ 森田 亘(@tascript) GMOペパボエンジニア Nuxt、Vue、TypeScript React、ReactNative(お休み中)

Slide 3

Slide 3 text

/FTU+4

Slide 4

Slide 4 text

લఏ Expressを使っている TypeScriptを使っている Nestは書いたことない 日本語の記事少なくて辛い 新しいことはみんなでやっていこうね!

Slide 5

Slide 5 text

/FTU+4 Node.jsのフルスタックフレームワーク デフォルトでTypeScriptを使用した開発が可能 DIを使用して疎結合なアプリケーション開発を実現 責務を分離することで冗長性の高い開発が可能

Slide 6

Slide 6 text

$POUSPMMFS 4FSWJDF 4FSWJDF 4FSWJDF 3FRVFTU $POUSPMMFS $POUSPMMFS ࠷খΞʔΩςΫνϟ

Slide 7

Slide 7 text

࠷খΞʔΩςΫνϟ ContollerはHTTPリクエストを受けてレスポンスを返すだけ Controllerでルーティングを決めておく ビジネスロジックはServiceに実装する ControllerごとにServiceをDIする $POUSPMMFS 4FSWJDF 4FSWJDF 4FSWJDF 3FRVFTU $POUSPMMFS $POUSPMMFS

Slide 8

Slide 8 text

$POUSPMMFS @Controllerデコレータでlocalhost:3000/catsが定義される コンストラクタの中で欲しいServiceを注入する

Slide 9

Slide 9 text

4FSWJDF @Injectableでインジェクションされることを宣言 ビジネスロジックを追加する

Slide 10

Slide 10 text

.PEVMF࡞੒ 使用する機能をカプセル化する 機能間の依存関係を解決する エンドポイント単位で作成するのがベター Controller、Service、Entityなどを宣言する 複数のmoduleから新たなmoduleを作成することもできる 1つのアプリケーションに対し最低1つのmoduleが必要

Slide 11

Slide 11 text

.PEVMF࡞੒ $BU.PEVMF 0XOFS.PEVMF %PH.PEVMF "OJNBM.PEVMF )VNBO.PEVMF "QQ.PEVMF

Slide 12

Slide 12 text

.PEVMF࡞੒ 最終的には1つのルートモジュールにまとめる エントリーポイントであるmain.tsにてimportして利用する module単位で依存関係を可視化できる 問題箇所を切り離しやすい $BU.PEVMF 0XOFS.PEVMF %PH.PEVMF "OJNBM.PEVMF )VNBO.PEVMF "QQ.PEVMF

Slide 13

Slide 13 text

.PEVMF࡞੒ ΤϯυϙΠϯτ୯Ґ @Moduleデコレータでmoduleを定義する 使用するControllerやServiceを定義

Slide 14

Slide 14 text

.PEVMF࡞੒ ϧʔτ importsに使用するmoduleを定義する 全ルートに対して実施するmiddlewareの宣言もここで実施

Slide 15

Slide 15 text

5ZQF4DSJQU ͱͷ਌࿨ੑ

Slide 16

Slide 16 text

%50 Data Transfer Object リクエストの型をチェックするためのオブジェクト interfaceかクラスで定義可能 クラスで書きましょう!

Slide 17

Slide 17 text

%50 クラスの場合 class-validatorでプロパティの型をチェックする

Slide 18

Slide 18 text

JOUFSGBDFͰ͍͍ͷͰ͸ʁ

Slide 19

Slide 19 text

1JQF Controller内におけるメソッドの引数をチェックする 受け取った引数の(型の変換 + )バリデーションを実施する バリデーションに通ったリクエストのみルートハンドラを実行する リクエストの型チェックをServiceの中でしなくてよくなる アプリケーションの疎結合が担保される interfaceの場合プロパティの再計算が実施できない (https://github.com/nestjs/nest/issues/1228)

Slide 20

Slide 20 text

1JQF $POUSPMMFS 4FSWJDF 4FSWJDF 4FSWJDF 3FRVFTU $POUSPMMFS $POUSPMMFS 1JQF

Slide 21

Slide 21 text

1JQF plainToClassで引数の情報をDTOクラスに変換 class-validatorのvalidateを使用してDTOオブジェクトとの比較

Slide 22

Slide 22 text

Ҏ্Λ౿·͑ͯ

Slide 23

Slide 23 text

/FTU+4ͷϝϦοτ ルーティングとビジネスロジックが分割されているので可読性が高い Fat Controllerになりにくい 単一責任の原則(SRP)により何を書くべきかが明瞭 async/awaitがデフォルトで使用可能(expressより導入しやすい) module単位、ルート単位でカスタマイズが簡単 TypeScript書ける人にはもってこい お約束はあるが割と直感的に書ける(個人差があるだろうけど)

Slide 24

Slide 24 text

/FTU+4ͷ೉ͦ͠͏ͳ఺ サブルーティングが切りにくい(moduleアーキテクチャの副作用) シェアするServiceが増えるとmoduleの分割が難しくなる InterceptorやPipeで型をCastしすぎないように注意 お作法に則るので人間が注意すべき点が多くなる 日本語の記事が…(一緒に増やしていきましょう!)

Slide 25

Slide 25 text

5ZQF03.

Slide 26

Slide 26 text

લఏ sequelize(-typescript)を使っている TypeORMを使ったことがない 新しいことはみんなでやっていきましょう!

Slide 27

Slide 27 text

5ZQF03. TypeScriptで利用可能なORM(ES5, ES6, ES7, ES8でも利用可能) Entity(Model)の定義からmigration or DBを直接操作 RepositoryパターンとActiveRecordパターンのいずれかで開発可能 取得したデータから型の恩恵を受けられる Nestの公式で利用を推奨

Slide 28

Slide 28 text

/FTU+4ͱͷ૊Έ߹Θͤ ormconfig.json(.js .env .yml .xml)をプロジェクトルートに配置 テーブルごとにentity(モデルに該当)を用意する entityにはテーブルの定義やメソッドを書く entityを使用するserviceとモジュールに注入する

Slide 29

Slide 29 text

PSNDPOpHKTPO typescriptの場合はtsconfig.jsonのoutDirに合わせて entities、migrations、subscribersのpathを作成する

Slide 30

Slide 30 text

&OUJUZ @Entityでentityの宣言とテーブル名の宣言をする sequelize-typscriptと大きく変わらない

Slide 31

Slide 31 text

4FSWJDF コンストラクタでentityからリポジトリを生成してDI リポジトリからテーブルを操作

Slide 32

Slide 32 text

.JHSBUJPO エンティティの変更履歴を確認して自動生成 DBにMigrationsテーブルが作成され実行履歴が確認できる リレーションも簡単に定義可能 TypeORM最高じゃん!

Slide 33

Slide 33 text

஫ҙ

Slide 34

Slide 34 text

.JHSBUJPOͷ᠘ DBに接続(サーバー立ち上げておかないと)migrationできない entityを作る・消すをしていると消したはずのentityのmigrationが残る Date型がstringとして帰ってくるケース

Slide 35

Slide 35 text

ௗ͡ΌΜʂ

Slide 36

Slide 36 text

ݪҼ

Slide 37

Slide 37 text

ݪҼ

Slide 38

Slide 38 text

͓·͑ͩͬͨͷ͔

Slide 39

Slide 39 text

ରࡦ distを消して再度npm run build npm run prestart:prodでも同じ ごめんねTypeORM

Slide 40

Slide 40 text

%BUFܕͷऔѻ͍ 例えばこんなentityを用意した場合は要注意

Slide 41

Slide 41 text

%BUFܕͷऔѻ͍ IUUQTHJUIVCDPNUZQFPSN UZQFPSNJTTVFT

Slide 42

Slide 42 text

%BUFܕͷऔѻ͍ ΧϥϜͷλΠϓΛEBUFʹ͢Δͱ %BUFܕΛఆ͍ٛͯͯ͠΋ TUSJOH͕ฦͬͯ͘Δ

Slide 43

Slide 43 text

໰୊ カラムの値をチェックする条件文が常に通らない(string型 ≠ Date型) asを使って型をcastし始める 型の正誤性が取れなくなる

Slide 44

Slide 44 text

ରࡦ time stampを使いましょう(Date型を返す) できるだけcastは使いたくないよね 時間の取扱いって難しいよね

Slide 45

Slide 45 text

5ZQF03.ͷϝϦοτ Migrationは癖があるけど、使い勝手がよい(ただしsynchronizeは…) 型の恩恵もそれなりに受けられる 導入までに時間がかからない(ほんの数分でできた) 非同期処理もスムーズに書けるNestとの相性は良好 リレーションで取得したプロパティにentityの型がつく

Slide 46

Slide 46 text

5ZQF03.ͷ೉͍͠ͱ͜Ζ タイプセーフなの? Date型の件から察するにコンパイル時に怒られない場合が高い 型をcastする可能性も高い subscribersでどうにかしてください、だと辛い

Slide 47

Slide 47 text

࣍ճҎ߱΍͍ͬͯ͘͜ͱ expressからNestJSにお引越し作戦(今回は間に合いませんでした) TypeORMとTypeScriptの親和性を検証

Slide 48

Slide 48 text

5IBOLZPV @tascript Fukuoka.ts