$30 off During Our Annual Pro Sale. View Details »

Prisma を活⽤した TypeScript チーム開発

SansanTech
PRO
September 12, 2023

Prisma を活⽤した TypeScript チーム開発

■イベント
TypeScriptを活用した型安全なチーム開発
https://sansan.connpass.com/event/292695/

■登壇概要
タイトル:Prisma を活⽤した TypeScript チーム開発
登壇者:技術本部 Digitization部 データ化グループ 湯村 直樹

■Digitization部 エンジニア 採用情報
https://media.sansan-engineering.com/digitization

SansanTech
PRO

September 12, 2023
Tweet

More Decks by SansanTech

Other Decks in Technology

Transcript

  1. Prisma を活⽤した
    TypeScript チーム開発
    技術本部 Digitization部 データ化グループ
    湯村 直樹

    View Slide

  2. 写真が入ります
    2019年 Sansan株式会社に新卒⼊社。
    名刺データ化システムなど複数のシステムの開発を
    経て、現在はデータ⼊⼒システム⽤の認証基盤の開
    発に従事。
    湯村 直樹
    Sansan株式会社
    Digitization部 データ化グループ

    View Slide

  3. データ化システムの認証基盤
    - Digitization部では複数のデータ化システムを開発している。
    - データ化システムを利⽤する⽅のアカウント管理、⼊⼒システムへの
    SSO を可能にする認証基盤を開発している。
    - 認証基盤では TypeScript と Prisma を採⽤している。

    View Slide

  4. Prisma とは?
    - Prisma は ORM
    - Prisma のスキーマを single source of truth として、アプリケーションの
    モデルの型とデータベースのマイグレーションファイルを⽣成できる。

    View Slide

  5. Prisma とは?
    アプリケーションのモデル
    DB のスキーマ

    View Slide

  6. Prisma は next-generation ORM
    - Prisma は従来の ORM とは異なるデータマッパー (※)
    - アプリケーションのモデルと DB のスキーマのマッピングは、マッピン
    グ⽤のクラスではなく、Schema から⽣成された Prisma のクライアン
    トが⾏う。
    - アプリケーションのモデルはクラスで定義していたのに対して、Prisma
    では TypeScript の型が⽣成される。
    - これによって型安全性を得ることができる。
    (※) Is Prisma an ORM?
    https://www.prisma.io/docs/concepts/overview/prisma-in-your-stack/is-prisma-an-orm

    View Slide

  7. 実際に Prisma を使う
    - 素直に使うとデータの完全性を守るのが難しい。
    Email のドメインは会社に登録された
    ものである必要があった

    View Slide

  8. データの完全性をどう守るのか

    View Slide

  9. Active Record パターンでの実装
    - DB のテーブルに対応したクラスに、データアクセスのロジックとビジ
    ネスロジックを持たせる。
    - データの完全性はレコード追加時に担保できればいい。
    - インスタンスのメソッドを利⽤するために、Prisma Client が返すオブジ
    ェクトからインスタンスを⽣成する。

    View Slide

  10. レコード追加時に
    完全性を担保する

    View Slide

  11. Data Mapper パターンでの実装
    - データアクセスの役割を持つクラスを分ける。
    - データの完全性をモデルクラスで担保する。
    - モデルクラスのインスタンスを完全なデータとして信頼する。
    - DB から取得した値は完全なデータとして扱う。

    View Slide

  12. インスタンス⽣成時に
    完全性を担保する
    完全なデータとして
    信頼する

    View Slide

  13. 改めて Prisma が従来の ORM とどう違うのか
    - Prisma は従来の ORM とは異なるデータマッパー (※)
    - アプリケーションのモデルと DB のスキーマのマッピングは、マッピン
    グ⽤のクラスではなく、Schema から⽣成された Prisma のクライアン
    トが⾏う。
    - アプリケーションのモデルはクラスで定義していたのに対して、Prisma
    では TypeScript の型が⽣成される。
    - Prisma によって⽣成された型と Prisma Client の関数を再実装している
    ことになるのでは?
    (※) Is Prisma an ORM?
    https://www.prisma.io/docs/concepts/overview/prisma-in-your-stack/is-prisma-an-orm

    View Slide

  14. プレーンなオブジェクトを使った実装
    - プレーンな JavaScript のオブジェクトをそのまま扱う。

    View Slide

  15. View Slide

  16. プレーンなオブジェクトを使った実装
    - クラスに変換する必要がない。
    - クラスで実現できていたカプセル化の実現が困難。
    - モジュールが肥⼤化しやすい。

    View Slide

  17. Prisma Client Extensions
    - model
    - アプリケーションのモデルにメソッドを定義できる。
    - client
    - Prisma Client にメソッドを定義できる。
    - query
    - Prisma Client のクエリを加⼯できる。
    - result
    - Prisma Client の返すオブジェクトにメソッドを定義できる。

    View Slide

  18. Prisma Client Extensions
    result
    client
    model
    query

    View Slide

  19. model の拡張
    - モデルにレコードを追加するメソッドを追加する。

    View Slide

  20. query の拡張
    - create の実⾏時に値を検証する。

    View Slide

  21. result の拡張
    - Prisma Client が返すオブジェクトにメソッドを追加する。

    View Slide

  22. Prisma Client Extensions まとめ
    - データの変換処理を⾏わず、型安全にビジネスロジックを実装できる。
    - $allModels と $allOperations を利⽤して、モデルやオペレーションをま
    たいだ共通処理も実装できる。
    - 複数のモデルが関連する処理を書きにくい。
    - 関連するモデルを都度 DB から引き直す。
    - Prisma.defineExtension を返す関数の引数に関連するモデルを渡す。
    - Prisma 特有の知識が求められる。

    View Slide

  23. 認証基盤で採⽤したアプローチ
    - クラスを利⽤した Data Mapper のような考え⽅でプレーンなオブジェ
    クトを利⽤する。
    - クラスに変換する必要がないので、データの取得は直接 Prisma Client
    を利⽤する。
    - データの完全性をビジネスロジックを扱うモジュールで担保する。
    - ビジネスロジックを扱うモジュールで⽣成されたオブジェクトを完全な
    データとして信頼する。
    - 状態ごとに型を分けると、状態ごとのロジックを持たせやすい。
    - コンパイル時に意図しない状態に気づくことができる。

    View Slide

  24. View Slide

  25. 不正な値を渡すと
    コンパイルに失敗する

    View Slide

  26. 認証基盤で採⽤したアプローチ
    - 型と関数を組み合わせることで状態に特化したロジックを実装しやすい。
    - データの完全性をコンパイル時に担保しやすい。
    - 型が増えるとそれらの関係を把握するのが難しくなる。
    - コントローラーから関数を呼び出す側の実装が増えるケースがある。

    View Slide

  27. [補⾜] 共通のクエリを実装するには?
    - satisfies (※)
    - ビルダーパターン
    (※) How TypeScript 4.9 `satisfies` Your Prisma Workflows
    https://www.prisma.io/blog/satisfies-operator-ur8ys8ccq7zb

    View Slide

  28. [補⾜] satisfies を利⽤した共通のクエリ
    - 型の Widening を防ぎながらクエリを記述できる。

    View Slide

  29. - Fluent な API を提供できる。
    [補⾜] ビルダーパターンを利⽤した共通のクエリ

    View Slide

  30. まとめ
    - 継続的にチーム開発を⾏うためにはデータの完全性を保つ仕組みが必
    要。
    - TypeScript と Prisma では様々なアプローチが可能。
    - 重要なのはどのパターンを採⽤するかではなく、重要な原則を守るため
    の仕組み、共通認識を持つこと。

    View Slide

  31. View Slide