Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
NestJS-tRPCと戦術的DDDのいいとこどりをしてバックエンドTypescriptの設計...
Search
与謝秀作
March 17, 2025
Technology
1
490
NestJS-tRPCと戦術的DDDのいいとこどりをしてバックエンドTypescriptの設計をした話
与謝秀作
March 17, 2025
Tweet
Share
Other Decks in Technology
See All in Technology
Terraformで構築する セルフサービス型データプラットフォーム / terraform-self-service-data-platform
pei0804
1
170
未経験者・初心者に贈る!40分でわかるAndroidアプリ開発の今と大事なポイント
operando
5
480
Agile PBL at New Grads Trainings
kawaguti
PRO
1
420
5分でカオスエンジニアリングを分かった気になろう
pandayumi
0
240
エラーとアクセシビリティ
schktjm
1
1.2k
新アイテムをどう使っていくか?みんなであーだこーだ言ってみよう / 20250911-rpi-jam-tokyo
akkiesoft
0
250
Obsidian応用活用術
onikun94
2
490
BPaaSにおける人と協働する前提のAIエージェント-AWS登壇資料
kentarofujii
0
140
250905 大吉祥寺.pm 2025 前夜祭 「プログラミングに出会って20年、『今』が1番楽しい」
msykd
PRO
1
830
「どこから読む?」コードとカルチャーに最速で馴染むための実践ガイド
zozotech
PRO
0
320
Practical Agentic AI in Software Engineering
uzyn
0
110
これでもう迷わない!Jetpack Composeの書き方実践ガイド
zozotech
PRO
0
400
Featured
See All Featured
Thoughts on Productivity
jonyablonski
70
4.8k
A Tale of Four Properties
chriscoyier
160
23k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
18
1.1k
Agile that works and the tools we love
rasmusluckow
330
21k
Art, The Web, and Tiny UX
lynnandtonic
303
21k
What’s in a name? Adding method to the madness
productmarketing
PRO
23
3.7k
Optimising Largest Contentful Paint
csswizardry
37
3.4k
Into the Great Unknown - MozCon
thekraken
40
2k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
33
2.4k
Building Applications with DynamoDB
mza
96
6.6k
Designing Experiences People Love
moore
142
24k
Intergalactic Javascript Robots from Outer Space
tanoku
272
27k
Transcript
NestJS-tRPCと戦術的DDDのい いとこどりをしてBackend Typescriptの設計をした話 by Ficilcom CEO YOSA
自己紹介 東京大学工学部システム創成学科卒業 日鉄ソリューションズ(SIer) :システムエンジニア bestat(松尾研系スタートアップ) :機械学習エンジニア ZOZO(自社サービス) :推薦エンジニア 独立、現在2個目のプロダクトを開発中(今日はここの話) ←Web
DB Press vol.129 「レコメンドエンジン総実装」 ↓ https://zenn.dev/yosashusaku
祝!2年ぶりの開催 この2年でNestJSの(個人的に一番の)大きな変化といえば、、、
NestJS tRPCのローンチ(2024/06) https://www.nestjs-trpc.io/ tRPCの作者(KevinEdry) が開発 →Monorepo内のBackend Typescriptとして有力 な 候補に
tRPCとは client/serverでTS の型を共有 Monorepo前提 →とにかく開発体 験がいい!!
前提条件:Turborepoを使った開発 https://turbo.build/repo/ Vercel製のTS/JS専用Monorepo管理ツール - リモートキャッシュ - タスクの依存解決 - テストやビルドの並列実行 Monorepo開発における強力な機能が多い
(Full TS前提だと特におすすめ) pnpm workspaceの拡張で右図のような ディレクトリ構成になっている
NestJS tRPCの設定 apps/api/src/app.module.ts packages/trpc/@generatedに自動生成 →フロントから呼び出せる
NestJS tRPCの実装例 NestJS tRPC専用のデコレータ DTOの代わりに Zodでスキーマ定義 (InputとOutputに使う フロントと型を共有) このサンプルでは1ファイルに 書いているが、実際に
Module内は Router / Schema / Service で構成される。
NestJS tRPCのその他のメリット Validationの違い:Zodになったことでフロントと共有できるテクニックが使える class-validator → Zod
おまけ:tRPC-Panel Swagger UIのtRPC版 APIエンドポイントの Documentを自動生成
NestJSでもMonorepo構成を 活かしたtRPCによる開発体験を 得ることができるゾ さて、 NestJSを使った開発に入る前に
NestJSは巷で言われているように too much なフレームワークなのだろうか?
APIサーバの役割をDDDの層に分解すると
NestJSの機能を当てはめると Controller / Router DTO / Schema Service
Serviceファイルに詰め込み過ぎじゃない? Serviceファイルにドメイン層・ユースケース層・インフラ層の責務を持たせる (Fat Service問題)のは無謀ではないか →改修困難なコード、人によってバラツくコーディングルール NestJSがtoo muchというのは嘘だと思う ※むしろnot enoughに感じた
NestJSで足りない部分は戦術的DDDで補う DDDの部分はpackages/coreに切り出そう! →ドメイン層とユースケース層はapps/apiを離れて packages/coreに移動する。 apps/api:NestJS(DI、デコレータなど) packages/core:DDD(domain、usecase、error) それぞれの文脈で開発を言葉を分けられる
戦略的DDDの構成要素 ドメイン層 - ビジネスロジックをエンティティや値オブジェクトに閉じ込め、純粋なビジネスルール として実装します。 - entity / value-object /
aggregate / domain-service / repository(I/F) ユースケース層 - ユースケースに沿った処理を実装し、ドメイン層のオブジェクトを組み合わせてビジ ネスプロセスを実現します。 インフラ層 - 永続化や外部サービスとの連携など、技術的な実装を担います。ここでは、Prisma などのORMが利用され、実際のデータアクセスを管理します。
ドメイン駆動設計における依存の方向 api:ライブラリや外部アクセス (ORM等)に依存する core:純粋なビジネスロジックを表現 ライブラリ等に依存しない PureなTypescriptで実装する apiはcoreに依存する。 それぞれ分離することで、TestableでSOLIDな構成になる。
Turborepoを使った依存関係の管理 packages/core/package.json 余計なライブラリを入れない apps/api/package.json dependenciesでcoreへの依存を定義 core → api の順にtestやbuildを実行 DDDの依存関係をpackageで管理できた
依存方向のディレクトリ構成対応 ① ② ③ ① ② ③ ※依存元→依存先
依存性逆転の法則(実例) インフラ層を リポジトリに注入 (=依存性逆転) Repository(I/F) を使ってusecase を定義
依存性逆転の法則(実例解説) 前ページの実装例では AuthJSを活用して認証を行っているため、api配下ではAuthというModuleに属してい る。 ところが、core配下ではAuthJSというライブラリには依存したくないため、 ”createUser” といったビジネスドメインでの定義をしている。 ↓ core配下をPureなTypescriptを使って(=外部ライブラリやサードパーティに依存せず) ビジネスドメインを表現している。
いつでもNestJSを剥がせる (↑NestJSのmeetupで言うことじゃない!)
まとめ Tureborepoの性質をフル活かすことで、 ①NestJSでもtRPCという極上の開発体験を得られる ②NestJSとTS DDDのいいとこどりをした開発ができる
告知①:エンジニア募集中 Typescript DDDだけじゃなくて おもしろい技術スタック使ってるよ! 募集職種:Typescript芸人 プロダクトエンジニア 建設業というドメイン (→DDDを使いたかった)
告知②:TSKaigi 2025開催
ご清聴ありがとうございました