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
650
NestJS-tRPCと戦術的DDDのいいとこどりをしてバックエンドTypescriptの設計をした話
与謝秀作
March 17, 2025
Tweet
Share
Other Decks in Technology
See All in Technology
Snowflake導入から1年、LayerXのデータ活用の現在 / One Year into Snowflake: How LayerX Uses Data Today
civitaspo
0
2.7k
Directions Asia 2025 _ Let’s build my own secretary (AI Agent) Part 1 & 2
ryoheig0405
0
110
Agent Skillsがハーネスの垣根を超える日
gotalab555
7
4.9k
AWS Lambda durable functions を使って AWS Lambda の15分の壁を超えてみよう
matsuzawatakeshi
0
110
松尾研LLM講座2025 応用編Day3「軽量化」 講義資料
aratako
14
4.7k
Oracle Database@Google Cloud:サービス概要のご紹介
oracle4engineer
PRO
1
800
Oracle Database@AWS:サービス概要のご紹介
oracle4engineer
PRO
2
540
SES向け、生成AI時代におけるエンジニアリングとセキュリティ
longbowxxx
0
260
AI with TiDD
shiraji
1
330
戰略轉變:從建構 AI 代理人到發展可擴展的技能生態系統
appleboy
0
170
AWSの新機能をフル活用した「re:Inventエージェント」開発秘話
minorun365
2
520
Redshift認可、アップデートでどう変わった?
handy
1
120
Featured
See All Featured
ラッコキーワード サービス紹介資料
rakko
0
1.9M
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
25
jQuery: Nuts, Bolts and Bling
dougneiner
65
8.3k
Getting science done with accelerated Python computing platforms
jacobtomlinson
0
84
The Cult of Friendly URLs
andyhume
79
6.7k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
5k
Paper Plane (Part 1)
katiecoart
PRO
0
2.5k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.5k
Ruling the World: When Life Gets Gamed
codingconduct
0
120
Writing Fast Ruby
sferik
630
62k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.6k
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開催
ご清聴ありがとうございました