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

ゆるふわCQRS入門

y_ahiru
May 15, 2023
530

 ゆるふわCQRS入門

スタフェス Meetup #3 ( https://stafes.connpass.com/event/279671/ ) で発表した内容です

y_ahiru

May 15, 2023
Tweet

Transcript

  1. // 商品申請集約 type ProductApplication = { id: string; productId: string;

    // 申請と紐づく商品 reviewStatus: ReviewStatus; // 審査ステータス content: ApplicationContent; // 申請内容色々 } // 商品集約 type Product = { id: string; productName: string; // ... } 商品申請機能開発中のお悩み紹介 9
  2. 15

  3. ゆるふわ CQRS アプリケーションモデルにだけエッセンスを適用 書き込みと読み込みでモデルを分ける データソースは RDBMS 1つ Event Sourcingは採用しない! 読み込みモデル

    -> 書き込みモデルの依存は少しなら許しちゃう ※ Segregation出来てないので、 CQRSと呼んだら怒られるかもしれない ゆるふわCQRSの紹介 18
  4. 19

  5. ReadModel type ProductApplication = { id: string; product: Product; //

    Read Model の商品 reviewStatus: ReviewStatus; content: ApplicationContent; } ゆるふわCQRSの紹介 23
  6. Presenter type HalJsonProductApplication = { id: string; // ... _embedded:

    { product: HalJsonProduct; }; _links: { self: { href: string }; }; } class HalJsonProductApplicationPresenter { make(application: ProductApplication): HalJsonProductApplication { // 変換処理 } } ゆるふわCQRSの紹介 25
  7. QueryService interface ProductApplicationQueryService { // 詳細画面などで必要になる、ID が一致するReadModel を引っ張ってくるやつ findOne: (id:

    string) => Promise<ProductApplication | null>; // 一覧画面のページネーションとかで必要になるやつ paginate: (page: number, perPage: number) => Page<ProductApplication>; // 複雑な検索などもOK relatedApplications: (id: string) => Promise<ProductApplication[]> } // インターフェースを切るならデータソースごとに実装を作るイメージ class MySqlProductApplicationQueryService implements ProductApplicationQueryService { // ... } class InMemoryProductApplicationQueryService implements ProductApplicationQueryService { // ... } ゆるふわCQRSの紹介 27
  8. Controller などはこんな感じに... class ShowProductApplicationAction { private readonly presenter: HalJsonProductApplicationPresenter; private

    readonly queryService: ProductApplicationQueryService; async invoke(req: Request): Promise<Response> { const application = await this.queryService.findOne(req.query('id')); if (application === null) { return new Response(404); } const jsonString = JSON.stringify(this.presenter.make(application)); return new Response(200, jsonString); } } ゆるふわCQRSの紹介 28