🦁

PHPerがNestJSでサーバーサイドTypeScriptに入門してみた(1)

2021/10/10に公開

はじめに(選んだ理由)

私事ですが、まもなく不惑になります 👵
20代の頃からずっとサーバーサイドはPHPメインで来て、そろそろサーバーサイドの別の言語を触ってみたいなーと思い、NestJS + TypeScriptを触ってみることにしました。

まずTypeScriptを選んだ理由としては、昨年副業でやらせてもらったReact+TypeScriptと、今年社内のスクラムチームで新プロダクト開発中にやっているAngular+TypeScriptの経験を通じて、
"PHP7,PHP8の型のあるPHPとTypeScriptは割とシームレスに行き来できる"
ということがわかっていたからです。

そのうえでなぜNestJSなのかというと、馴染み深いMVCでサーバーサイド書いていいんやで(雑な要約) https://docs.nestjs.com/techniques/mvc という記事をたまたま見かけたからです。

NestJS入門にあたって探したもの

MVCで書けることは前述の記事を読んでわかったのですが、長年Symfonyに甘やかされているので、単にMVCなだけだと既につらいです。
最低限で

  • DI
  • ORM
  • テンプレートエンジン…できればTwigと同じ文法で書きたい

がほしいなと思いました。

DI

NestJSのドキュメントで一発解決しました。
https://docs.nestjs.com/fundamentals/custom-providers

普段、「フレームワークに依存しないで生のクラスでロジックを書きたい」流派に属しているので( https://speakerdeck.com/77web/sofalsekodo-huremuwakufalsewai-demodong-kimasuka )ドメインロジックのクラスに @Injectable を書かないといけないのはぐぬぬ…という感じですが、まぁどうしても許せなければFactoryパターンを多用すればいいかと思い、これで解決としました。
@Injectable はAngularと同じような使い方でAngularに慣れていると使いやすいですね。

ORM

ActiveRecordでもギリギリ許容範囲ではあるものの、できればDoctrineと同じDataMapperがよかったので TypeScript ORM DataMapper TypeScript Hibernate 等でググりました。
比較的すぐ見つかりました。
MikroORM https://mikro-orm.io/

もう公式サイトのトップに載ってるコード例だけで、なんとなく親近感が湧いてしまいました。(Doctrineユーザーにはわかると思う、この気持ちw)

const user = em.find(User, 1);
user.name = 'update!';
await em.flush();

個人的に最も素晴らしいと思うのはDoctrineMigrationと同じようなmigration自動生成があることです! 💯

テンプレートエンジン

こちらも TypeScript twig TypeScript jinja 等とググって見つけました。
nunjucks https://mozilla.github.io/nunjucks/

サイトトップのテンプレート例が完全に違和感なかったのと、extendsとblockが使えるというので、これに決めました。

コード

まだ何もまともなロジックがない段階ですが↓に置きました。
https://github.com/77web/nest-mvc-playground

NestJSのデフォルトのテンプレートエンジンがnunjucksじゃなくてHandlebarsなので、main.tsで設定をごにょごにょ頑張ったりとか。
https://github.com/77web/nest-mvc-playground/commit/6ca254f1cc0e9a869c351eb0383c410954d3662f#diff-4fab5baaca5c14d2de62d8d2fceef376ddddcc8e9509d86cfa5643f51b89ce3d

MikroORMを使えるようにググって見つけたモジュールを設置してみたりとか。
https://github.com/77web/nest-mvc-playground/blob/main/src/module/orm/orm.module.ts

Symfonyでやるのと同じようにDB接続情報を.envで指定できるように試行錯誤とか。
https://github.com/77web/nest-mvc-playground/blob/main/config/mikro-orm.config.ts

DBを使った機能テスト書いてみたりとか。
https://github.com/77web/nest-mvc-playground/blob/main/src/controller/home.controller.spec.ts

ここから、ひとまずおなじみのTODOアプリを実装してみる予定です! 💪

Discussion