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

devio-2024-Introduction-golang-backend

mokonist
July 20, 2024
4k

 devio-2024-Introduction-golang-backend

mokonist

July 20, 2024
Tweet

Transcript

  1. Agenda 3 • gRPC • Protocol Buffer • connect-go •

    connect-query(React Query) • LayeredArchitecture • DI • Microservices • (おまけ)CQRS+Event Sourcing
  2. gRPC • Googleが開発したRPC(Remote Procedure Call) ◦ HTTP/2上で実装されたプロトコル ◦ メソッドを呼び出すような感覚でBackendを実装する ◦

    ストリーム、双⽅向通信など幅広く実装可能 • データモデルの定義が簡単にできるため、⾮常に便利 ◦ Microservicesとしても統括的に管理することが可能 6
  3. • Protocol Bufferから各⾔語向けにServerのInterfaceと Clientが⽣成できる ◦ めっちゃ精度良い ▪ Backendは⽣成されたInterfaceをImplement ▪ 使⽤側はClientをImportしてCallするだけ

    • 良くも悪くもRESTFulな設計とは別の考え⽅が出来る ◦ RPCなので単純なCRUD以外の要件などにも対応 ◦ Validation含めて、Protocol Bufferのエコシステムで対応 が出来る RESTと異なる点 8
  4. Microservice 26 gRPCとMicroservicesは相性が良い • パフォーマンス上のメリットももちろんあるが ◦ Protocol Bufferのエコシステムが最強 ▪ Server,

    Clientなど実装が楽 ▪ 各⾔語向けにも対応 ▪ Protocol Bufferの破壊的変更も検知可能 ▪ 各サービス毎にバラバラの実装をするより、gRPC, connet-goで喋る プロトコルを定めた⽅が楽 ◦ 各チームで分散して効率良く開発していく所において、ベストな選択 (個⼈的感想)
  5. • ざっくり解説 ◦ ビジネスドメインを軸とした開発⼿法と組織論 ◦ Entity, ValueObjectとしてドメインを定義 ▪ ユーザー、タスク、コメントなど ◦

    ドメイン知識をドメイン層で定義‧処理を⾏い、 正しいインスタンスしか存在出来ない状態とする ◦ 今回は実装的な側⾯でしか話しませんが ▪ 本来は1時間で収まりきらないくらいの物量 DDD(Domain-driven design) 36
  6. • 実装的な側⾯ ◦ ドメイン層は古典的なオブジェクト指向として実装され ることが多い ▪ task := new Task(props)

    ▪ task.Update(props) • → Taskの更新条件を満たしているのか等のロ ジックを、ドメインオブジェクトで実装する ◦ 永続化はRepository層として実装して、Repository層は DB等への保存/取得と、ドメインオブジェクトを⽣成し て返す DDD(Domain-driven design) 37
  7. “In the “Stereotypical Architecture” the domain was handling both Commands

    and Queries, this caused many issues within the domain itself.” 「ステレオタイプなアーキテクチャ」では、ドメインがコマンドと クエリの両⽅を処理しており、これがドメイン内に多くの問題を引 き起こしていた。 CQRSとは? 43 https://cqrs.wordpress.com/wp-content/uploads/2010/11/cqrs_documents.pdf
  8. CQRSとは? “Once the read layer has been separated the domain

    will only focus on the processing of Commands. These issues also suddenly go away. Domain objects suddenly no longer have a need to expose internal state, repositories have very few if any query methods aside from GetById, and a more behavioral focus can be had on Aggregate boundaries” リード層を分離したら、ドメインはコマンドの処理にのみ専念することになる。これによ り、いくつかの問題も突然解消される。ドメインオブジェクトは内部状態を公開する必要が なくなり、リポジトリはGetById以外のクエリメソッドをほとんど持たなくなり、アグリゲー トの境界に関してより⾏動に焦点を当てることができるようになる。 44 https://cqrs.wordpress.com/wp-content/uploads/2010/11/cqrs_documents.pdf
  9. • Command ◦ ビジネスロジックを処理して、Entityを適切に処理する事に集中 ◦ 書き込み結果等レスポンスは返さない • Query ◦ ドメインロジックは無く、データの取得に特化する

    ◦ ドメイン層を経由せず、直接データをDTO(Data Transfer Object) に沿った値として直接取得する(ドメイン知識は不要) ◦ ドメイン層におけるRepositoryとは別にQueryServiceを定義して 直接クエリする Command/Query 45
  10. Event Sourcing 50 • CQRS + ESでは、従来のCURDのような永続化されたステートを元 にした設計ではない • Commandとして変更内容/処理内容を定義して、EventStoreに

    シーケンシャルに保存する • 「変更内容/処理内容」をEventStoreから取得して、古い順から再 ⽣することで、Entityの現在の状態を知ることが出来る
  11. Event sourcing - Event 53 { "event": "CreatedTask", "version": "1",

    "payload": { "taskId": "123e4567-e89b-12d3-a456-426614174000" , "title": "Implement CQRS", "description": "Create and implement CQRS architecture for the project" , }, "timestamp": "2024-01-01T00:00:00Z" } CreatedTaskEventの例
  12. Event sourcing - Event 54 { "event": "AssignedTask", "version": "2",

    "payload": { "taskId": "123e4567-e89b-12d3-a456-426614174000" , "assign": "2b7025e3-199e-403e-b3a6-4aa9413e7028" , }, "timestamp": "2024-01-01T00:00:00Z" } AssignedTaskEventの例
  13. つまり 57 • Commandの責務はユースケース別のコマンドを処理し て、ドメインロジックに集中する ◦ ドメインロジックに基づいて処理を⾏う ◦ その結果をイベントストアに保存 •

    イベントストアに保存された値を元に、Snapshotを作成 する ◦ 例)DynamoDB Streams, Pub/Sub等 • Queryの責務はユースケース別のDTOを取得して返却 ◦ 都合の良いデータを取得して、返却する事に集中
  14. CQRS, ESがマッチするプロジェクト • CQRS ◦ ビジネスロジックが複雑で、CRUDでの実装が苦しい場合 ◦ N+1となり苦しい場合 ◦ 柔軟にReadのレスポンスを変えたい、複雑なクエリが必要等、Readに関

    して様々な要件がある場 • Event Sourcing ◦ 監査等で過去の状態、変更ログ等を保持‧分析する必要がある場合 ◦ 複数サービスと⽂字通りのイベントドリブンな連携をしたい場合 マッチするプロジェクト 59
  15. 使う必要が無いプロジェクト • CQRS ◦ ドメインがシンプル、複雑なビジネスロジックが無い場合 ▪ 既存のRepository層実装でも問題が無い場合等 • 参照箇所が複数⽣まれるため、煩雑になる可能性あり •

    Event Sourcing ◦ 厳密な変更履歴を保持する必要が無い場合 ◦ Repository層を通さず、Infra層でDTOを実装等、過去のイベント保 持無しでも解決が出来る場合 使う必要が無いプロジェクト 60
  16. 61