Slide 1

Slide 1 text

1 Next.jsで Clean ArchitectureとDDD Hyunseung Park / 朴賢勝 Uzabase Inc, Japan 2021.11.24 v12リリースを踏まえ、Next.jsの採用を考える 1

Slide 2

Slide 2 text

2 自己紹介 NewsPicks Expertとは - Next.jsを採用した理由 - Clean ArchitectureとDDDを採用した理由 実践 まとめ 01 02 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 2 アジェンダ 04 03

Slide 3

Slide 3 text

3 @dordieux dordieux ● 朴 賢勝(Park Hyunseung) ● 株式会社ユーザベース 2020/11/01 ~ ○ 2019年新卒から中途入社 ○ SPEEDA, NewsPicks Expertなど 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 3 自己紹介

Slide 4

Slide 4 text

4 NewsPicks Expertとは 4

Slide 5

Slide 5 text

5 5 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 5 エキスパートプラットフォーム「NewsPicks Expert」 “ 自分が持っている知識を社会のために役立てたい ” “ これまで培ってきた知見を異業種で生かしてみたい ” “ 社外の活動を通じて、知的な刺激を得たい ” エキスパートに登録いただく方々の想いはそれぞれですが、 共通していることは「専門性を生かし、貢献したい・活躍したい」という想い。 最先端ビジネス領域の第一人者や、その道30年の経験者など、 様々な業界・分野で実務経験を積んだ数多くの方々に、 「エキスパート」として登録いただいています。 私たちは「Expert First」を念頭に、 エキスパートとして登録いただく個人の方を第一に考え、 専門性を持った個人の方が活躍する機会を作り続けてまいります。 個人一人ひとりが活躍する機会を増やし、知見の流通を促すことで、 世界中の問題解決やイノベーションを加速させ、 エキスパートの皆様と一緒により良い世界をつくっていきたいと考えています。 MESSAGE

Slide 6

Slide 6 text

6 NewsPicks Expert 案件例(専門コメント FLASH Opinion:フラッシュオピニオン) クライアントの質問に対し、専門的な知見をお持ちであると思われる方に、メールで質問が届きます。 24時間以内に、200〜800文字で、ご回答をお願いします。 FLASH Opinionとは、クライアントの質問に対し、24時間以内にご回答いただくQ&A形式の案件です。 (FLASH Opinionに回答いただいたエキスパートに「インタビューもしたい」というケースも数多くございます) クライアント SPEEDAで 質問投稿 エキスパート 24時間以内に 200字〜800字で 5名以上が回答 SPEEDAで 回答確認 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 6

Slide 7

Slide 7 text

7 7 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 7 NewsPicks Expert (https://newspicks.expert/) https://newspicks.expert

Slide 8

Slide 8 text

8 8 Next.jsを 採用した理由 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 8

Slide 9

Slide 9 text

9 Next.jsを採用した理由 9 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 9 - Reactベース - 素早く始められる - API Routes

Slide 10

Slide 10 text

10 10 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 10 マイクロフロントエンド・マイクロサービス 各プロジェクトチームで開発をしている しかしSPEEDAにReactはなかった

Slide 11

Slide 11 text

11 素早く始められる 11 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 11 typescript・Routing・SSR/SSG・ Webpack/babel ・Fast Refresh・ Image Optimization ・・・

Slide 12

Slide 12 text

12 API Routes 12 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 12 マイクロサービスアーキテクチャ

Slide 13

Slide 13 text

13 API Routes 13 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 13 マイクロサービスアーキテクチャ BFFとして使う

Slide 14

Slide 14 text

14 14 フロントエンドで Clean Architectureと DDDを採用した理由 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 14

Slide 15

Slide 15 text

15 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 15 チーム構成 - チームは3~5人で構成されています - 定期的にチームメンバーは入れ替えます - 勤務時間、技術はチームによって異なります イヌチーム ネコチーム クマチーム

Slide 16

Slide 16 text

16 16 Clean ArchitectureとDDDを 全社的にやってる 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 16

Slide 17

Slide 17 text

17 17 Clean ArchitectureとDDDを 全社的にやってる 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 17 E2E・Unit Test

Slide 18

Slide 18 text

18 18 Clean ArchitectureとDDDを 全社的にやってる 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 18 E2E・Unit Test チームを移動しても すぐに馴染みやすい

Slide 19

Slide 19 text

19 Clean ArchitectureとDDD 19 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 19 一定のビジネスロジックは存在する Componentとロジックを分離する

Slide 20

Slide 20 text

20 実践 20

Slide 21

Slide 21 text

21 21 ※Clean Architectureと DDD自体の説明は省略します 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 21

Slide 22

Slide 22 text

22 22 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 22 Dependency Injection フロントエンドでも同じく 依存性逆転が必要

Slide 23

Slide 23 text

23 23 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 23 Dependency Injection ビジネスロジックをしっかり テストしたい ロジックを分離して外部要素と 切り離してテストする

Slide 24

Slide 24 text

24 24 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 24 Dependency Injection TypeScriptのDI Containerのライブラリも充実してる - Inversify - TSyringe - Typed Inject - TypeDI - 自作 ・・・

Slide 25

Slide 25 text

25 25 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 25 @injectable() export class UserUseCase { constructor(@inject("UserPort") readonly userPort: UserPort) {} async getSelf(): Promise { return await this.userPort.find(); } } // DIコンテナーに追加 container.register("UserPort", { useClass: UserGateway });

Slide 26

Slide 26 text

26 26 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 26 フロントエンドだけでなく、 プロダクト全般

Slide 27

Slide 27 text

27 27 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 27 フロントエンドだけでなく、 プロダクト全般 フロントエンドに合わせて 同心円も考え直す必要がある

Slide 28

Slide 28 text

28 28 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 28 domain Use Case Gateways Controllers API View Storage

Slide 29

Slide 29 text

29 29 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 29 domain Use Case Gateways Controllers API view Storage View Controller UseCase Port state

Slide 30

Slide 30 text

30 30 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 30 domain Use Case Gateways Controllers API view Storage View Controller UseCase Port state

Slide 31

Slide 31 text

31 31 Reactのstateと Clean Architectureのドメインを 紐付ける 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 31

Slide 32

Slide 32 text

32 32 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 32 export interface ExpertState { expertId: number; mailAddress: string; name: string; } export class Expert { constructor( readonly expertId: ExpertId, readonly mailAddress: MailAddress, readonly name: Name, ) {} } state domain

Slide 33

Slide 33 text

33 33 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 33 async function fetchMyPage() { return await container.resolve(MyPageController).get(); } const MyPage: NextPage = () => { const [profile, setProfile] = useState({}); useEffect(() => { const run = async () => { const expert = await fetchMyPage(); setProfile({expert.id, expert.name ・・・}); }, []} }

Slide 34

Slide 34 text

34 34 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 34 @injectable() export class MyPageController { constructor(readonly expertUseCase: ExpertUseCase) {} async get(): Promise { const me = await this.expertUseCase.getSelf(); return { expertId: me.expertId.value, name: me.name.value ... } } }

Slide 35

Slide 35 text

35 35 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 35 export interface ExpertState { expertId: number; mailAddress: string; name: string; } export class Expert { constructor( readonly expertId: ExpertId, readonly mailAddress: MailAddress, readonly name: Name, ) {} } state domain

Slide 36

Slide 36 text

36 36 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 36 domain Use Case Gateways Controllers API view Storage View Controller UseCase Port state

Slide 37

Slide 37 text

37 37 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 37 domain Use Case Gateways Controllers API view Storage View Controller UseCase Port Presenter state

Slide 38

Slide 38 text

38 38 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 38 domain Use Case Gateways Controllers API view Storage View Controller UseCase Port Presenter state

Slide 39

Slide 39 text

39 39 ReactのComponentで DI Container・Clean Architecture など意識したくない 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 39

Slide 40

Slide 40 text

40 40 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 40 async function fetchMyPage() { return await container.resolve(MyPageController).get(); } const MyPage: NextPage = () => { const [profile, setProfile] = useState({}); useEffect(() => { const run = async () => { const expert = await fetchMyPage(); setProfile(expert); } }

Slide 41

Slide 41 text

41 41 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 41 const MyPage: NextPage = () => { const profile = useProfile(); return ( <> ・・・ > ) } function useProfile() { const expert = await container.resolve(MyPageController).get(); return {expert.id, expert.name ・・・}; }

Slide 42

Slide 42 text

42 42 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 42 domain Use Case Gateways Controllers API view Storage View Controller UseCase Port Presenter state

Slide 43

Slide 43 text

43 まとめ 43

Slide 44

Slide 44 text

44 44 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 44 よかった点 - Next.jsでClean Architecture・DDDの構成で リリースできた - ReduxやRecoilなど使わずにstateの管理ができた - Componentでビジネスロジックを持たなくなって 綺麗になった

Slide 45

Slide 45 text

45 45 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 45 伸び代 - Next.jsのfeatureを上手く使えてないかも - SSR/SSG・細々な最適化 - custom hooksやcontextなどできてなかった

Slide 46

Slide 46 text

46 46 【 Uzabase×forkwell 】v12リリースを踏まえ、 Next.jsの採用を考える  / 46 https://hatenanews.com/articles/20 21/05/26/103000 https://hatenanews.com/articles/20 21/06/29/103000 積極採用中です!