Upgrade to Pro — share decks privately, control downloads, hide ads and more …

TechPlay22_06_28_Full TypeScriptで新規プロダクトを立ち上げた際に実践した設計と反省

79d1f8ec70d4c77a2eb30052bef0fe35?s=47 kakehashi
June 30, 2022
250

TechPlay22_06_28_Full TypeScriptで新規プロダクトを立ち上げた際に実践した設計と反省

79d1f8ec70d4c77a2eb30052bef0fe35?s=128

kakehashi

June 30, 2022
Tweet

Transcript

  1. Full TypeScriptで新規プロダクトを 立ち上げた際に実践した設計と反省 株式会社カケハシ 小室 雅春

  2. 小室雅春 (コムロ マサハル) • WEBソフトウェアエンジニア • 経歴 ◦ 某新聞社(2016 ~

    2022/05) ◦ 株式会社カケハシ(2021/06~) • TypeScript, SPA, Express, AWS CDK • 患者さんの服薬をサポートする新規プロダクトの立 上げを担当 自己紹介 @_hedrall hedrall https://blog.hedrall.work
  3. 1. 背景 2. 技術選定と設計 • 言語 • レポ管理 • アーキテクチャー

    • フロントエンド • バックエンド • テスト 3. まとめ アジェンダ
  4. カケハシとは? https://www.kakehashi.life/

  5. • 21年6月入社した当時、新規プロダクトの立上げの話があった ◦ => 患者さんの服薬を薬局がサポートするための業務システム • 明確なDeadLineはないが、概ね3, 4ヶ月くらいでMVP版をリリースした い ◦

    その後、正式リリース => スケールしていく前提 • リソースは、私 + 兼業メンバー2, 3名のサポート 新規プロダクト開発の背景 スピーディにプロダクトを立ち上げて、 PMFに向けたサイクルを回したい!
  6. • 薬局がWindows Desc/Tabで利用するJamstackな業務WEBアプリ ◦ SPAアプリ (SSR不要) • 患者の個人情報が含まれる ◦ (クライアント証明書による制限が必要)

    • 薬局が患者をサポートした履歴など、書き込みが必要 • (ログインセッションは既存の別システムと共有化する(SSO)) • 将来的に実装されうる機能が特定しきれていない ◦ 既存にない業務、今までになかったプロダクト 構築するシステムの特性
  7. • 開発速度 ◦ 軽量な技術スタックでTryErrorのサイクルを短縮 ◦ 効果の高いツールは、新興ツールでも利用する ▪ 捨てられる事が前提 • シンプルさ

    ◦ 兼業のメンバーや、今後加わるメンバーが理解しやすい • 属人化しない ◦ 一般的な技術 or 可換な技術 or 使いやすい技術 ◦ 整理されつつ、複雑化しないアーキテクチャー 技術選定・設計方針
  8. 2. 技術選定・設計

  9. • WEBフロントエンドを開発する以上必ず使う • 全部TypeScriptで無理なく開発可能 ◦ AWS CDK (2019 ~) により、IaC

    もTypeScriptで簡単に • 立ち上がり期、フルスタックなメンバーの多い環境 ◦ (周辺エコシステムを含む) コンテキストスイッチの最小化 ▪ 他の言語を導入する場合はコストを考慮する必要がある • (バックエンドに重い集計などはない) • TSの良さ ◦ 型によるドキュメンテーション効果の向上 ▪ 構造的部分型による人に優しい型 (情報量・可読性) 2.1 言語 => Full TypeScript!!
  10. • 最近のエディターは複数のtsconfig.jsonに対応 • フロント・バックが一体のシステム • 一部コードを共有したい ◦ Domain Model, DTO,

    コアロジック, 共通関数 ◦ FullTS環境では大きな利点 • cons ◦ コード共有は循環参照に気をつける ◦ precommit hook, eslintの設定などは工夫する 2.2 レポジトリ管理 => モノレポ Github Repository frontend backend infra package.json tsconfig.json ・・・ package.json tsconfig.json common
  11. • クリーンアーキテクチャー(CA)、DDDの手法を漸進的に導入する • CA ◦ ロジックの置き場を整理 ◦ コンポーネントを差し替えできるようにしておく ▪ β版からプロダクトのスケールの準備

    • DDD ◦ ドメインモデルを整備する ▪ ビジネス要件をコードに反映しやすくする ▪ ドキュメンテーションとしての価値 • 週2回 (+ 都度)、PdMと要件を整理 2.3 アーキテクチャー
  12. 実装にあたって参考にする物 出典: https://github.com/esakik/clean-architecture-python Clean Architecture 図22-2 典型的な例

  13. バックエンド(API) フロントエンド(SPA) Controller UseCase Repository DB MySQL HTTP Request

  14. バックエンド(API) フロントエンド(SPA) Controller UseCase Repository DB HTTP Request MySQL データモデルをどうするか?

  15. バックエンド(API) フロントエンド(SPA) Controller UseCase Repository DB MySQL HTTP Request Domain

    Model DAO DTO TypeORM (DynamoDBなら省略可能? ) ドメインモデルの改修サイクルで APIに破壊的な変更が入る事があ る 変換 変換
  16. Domain Model DAO TypeORM (DynamoDBなら省略可能? ) ドメインモデルの改修サイクルで APIに破壊的な変更が入る事があ る バックエンド(API)

    フロントエンド(SPA) Controller UseCase Repository DB MySQL HTTP Request リリース時の ダウンタイムを 許容するか? 変換 変換 DTO
  17. バックエンド(API) フロントエンド(SPA) Controller UseCase Repository DB MySQL 変換 UIComponent (View)

    Repository Hooks 変換 変換 Domain Model DAO DTO API Request
  18. • フレームワーク(Next.js, Angularなど)に依存したくない ◦ 素早くプロダクトを立ち上げる為に身軽でいたい ◦ たち上がりは早い? ▪ 当初知識がなくても利用しやすいが、将来的な学習コストが高い ◦

    不必要なツールに依存する ▪ ビルドに時間がかかる ▪ TryErrorサイクルに影響 ▪ 手を加えるのが大変 • 判断のポイント ◦ toCかtoBかで非機能要件が大きく異なる ▪ SSR(SEO)、パフォーマンス、負荷対策 • 大まかなトレンドは The State of JS などを参考 2.4 フロントエンド 前提
  19. • React ◦ 内部が全てJS ◦ TSによるドキュメンテーション効果が高い => 属人化しない ◦ ビルド開発環境が選びやすい

    => DX改善がしやすい • ビルド ◦ esbuild <= Webpackの100倍早い !! ▪ 軽量かつ可換 ▪ 話題のesbuildをさっくりと調査してみた ◦ ローカルは、expressとbrowsersyncでホスト ▪ Advent Calender: esbuild + React(TS) で実現する超軽量な開発環境 • パッケージ: pnpm <= npm よりも高速でエコ • Inversify.js => DIコンテナ ◦ APIクライアントをstabと差替し、standaloneで起動 2.4 フロントエンド React
  20. • 開発速度の向上!ドキュメント作成! • とはいえ、活用方法は十人十色 • TSOAを採用 ◦ CodeFirstでOpenAPIスペックを生成 ◦ 更にOpenAPI-generatorでAPIクライアントを生成

    • => 手間なく、フロントとバックの整合性を担保 • => ボイラープレート部分を自動生成 詳細な活用方法 ▼ Code Firstで疲弊しないOpenAPI活用方法 2.5 OpenAPIの活用 OpenAPI
  21. バックエンド コントローラを記述 import express from 'express'; import { Controller ,

    Get, OperationId , Body, Request, Route, Security } from 'tsoa'; @Route('user') export class UserController extends Controller { constructor (private service: IUserService) { super();} /** * ユーザ一覧取得 */ @Get('list') @Security(SECURITIES.COGNITO) @OperationId ('list-user' ) public async get( @Request() request: express.Request, @Body() params: InputDto ): Promise<OutputDto> { const res = await this .service.list( request. user, apiDtoConverter(params) ); return apiDtoConverters.user.list.serviceToOutput (res); } } Controller 後続の処理 変換 HTTP Request
  22. import express from 'express'; import { Controller , Get, OperationId

    , Body, Request, Route, Security } from 'tsoa'; @Route('user') export class UserController extends Controller { constructor (private service: IUserService) { super();} /** * ユーザ一覧取得 */ @Get('list') @Security(SECURITIES.COGNITO) @OperationId ('list-user' ) public async get( @Request () request: express.Request, @Body() params: InputDto ): Promise<OutputDto> { const res = await this .service.list( request. user, apiDtoConverter(params) ); return apiDtoConverters.user.list.serviceToOutput (res); } } Controller 後続の処理 変換 バックエンド コントローラを記述 GET: /user/listへのリクエストを処理 HTTP Request
  23. • schemaでのvalidationなど • Auth Middlewareの差し込み Controller 後続の処理 生成 バックエンド OpenAPI

    Spec  ボイラープレート 生成 HTTP Request
  24. Controller 後続の処理 バックエンド OpenAPI Spec  ボイラープレート フロントエンド(SPA) Component (View) Repository

    Controller (Presenter) 変換 API Client 生成 生成 生成 • schemaでのvalidationなど • Auth Middlewareの差し込み 型の効いた API Request ! DB HTTP Request
  25. • Testing Trophyを念頭に • 静的解析を頼る • Unitを減らして、Unitに縛られない • 統合テストはDBをモックしない ◦

    https://github.com/testjavascript/nodejs-integration-tests- best-practices • Github Actions で実行 2.6 Testing 出典: https://twitter.com/kentcdodds/status/960723172591992832?lang=zh-Hant
  26. • Goods ◦ 機能全体のテストができるので、安心感が ある ◦ 障害が発生した場合に、修正以降の動作 を保証できる • Bads

    ◦ テストデータの作成が大変 ▪ JSONで記述するSeeds ▪ APIによるMutationを利用 ◦ テストケースが網羅できない場合がある ▪ 細かな文言の違い ▪ 局所的に複雑なロジック ▪ => UnitTestで担保できないか? • Jestの起動が遅い? ◦ Jestのテストを高速実行する自作ツール 既 存のJestで書かれたテストを爆速実行するツール、uvu-jest を作りました 2.5 Testing 出典: https://twitter.com/kentcdodds/status/960723172591992832?lang=zh-Hant
  27. • 新規プロダクトの構築に際して、軽量な開発環境を工夫することで、順調 に開発・リリースすることができた 🎉 • 現在もより多くの薬剤師にご活用頂けるように、より加速してプロダクトを 成長中! • 次プロダクトを立ち上げるときに事前によく検討するべき事項がわかった 😆

    まとめ
  28. エンジニア採用中 • 医療分野にて社会的意義のある開発をしたい方 • アプリケーション構築に興味がある方 • フルスタックに開発をしたい方 • データの利活用に興味がある方 まずはカジュアル面談をご利用下さい!

    採用ページ
  29. 以上です! ありがとうございましたmm 採用ページ