👌

CQRS設計パターンをモダナイズする

2024/05/21に公開1

CQRSとは


CQRS(Command Query Responsibility Segregation、コマンド・クエリ責務分離)は、ソフトウェアアーキテクチャパターンの一つで、つまりシステムのコマンド部分をクエリ部分から分離します。基本的な考え方は、データの書き込み操作(コマンド)と読み取り操作(クエリ)を異なるモデルで扱うことです。これにより、スケーラビリティ/パフォーマンス/セキュリティの観点で柔軟な設計が可能となり、クエリ要件に合わせて最適化が実現できます。

CQRSの基本構成としては、

  • コマンドモデル(書き込みモデル):データの作成、更新、削除といった書き込み操作を担当します。このモデルは、データの整合性と一貫性を確保するために最適化されています。
  • クエリモデル(読み取りモデル):データの読み取り操作を担当します。このモデルは、クエリのパフォーマンスを最大化するために最適化されています。

の2つに分けるのが一般的です。

データベースの進化 ~サーバレス化と分散アーキテクチャ~

近年、データベース技術は劇的に進化しており、その一環としてサーバレス化と分散アーキテクチャが注目されています。

サーバレスデータベース

サーバレスデータベースは、クラウドサービスプロバイダが提供するデータベースサービスの一種で、インフラストラクチャの管理を必要とせずにデータベースを利用できる仕組みです。サーバレスアーキテクチャは、バックエンドのインフラストラクチャの管理をクラウドプロバイダに委ねることで、開発者がアプリケーションロジックに集中できるように設計されています。
近年では、DynamoDBやFirestoreといったNoSQLに限らず、RDBでもサーバレス化が進んでいます。具体的な例としては、AWS Aurora Serverless、PlanetScale(MySQL系)、Neon(Postgres系)などがあげられます。

https://aws.amazon.com/jp/rds/aurora/serverless/
https://planetscale.com/
https://neon.tech/

分散データベース

Cloud SpannerやTiDB、CockroachDBなどの分散データベースは、地理的に分散した環境での高可用性と低レイテンシを実現します。これにより、大規模なシステムでもスムーズに動作するアーキテクチャを構築できます。

https://cloud.google.com/spanner?hl=ja
https://pingcap.co.jp/tidb/
https://www.cockroachlabs.com/

データベースの進化がCQRSに与える影響

サーバレスデータベースと分散アーキテクチャにより、インフラ設計を気にしなくても高可用性や耐障害性が保証されたデータベースを構築できるようになりました。上図のCQRSパターンにあるようなデータベースの分離を行わなくても、これらのDBを導入するだけで運用管理の手間をかけずにProduction-readyなデータベースを構築できるようになっています。

自動生成されるバックエンドAPI

近年では、バックエンドAPIの自動生成ツールが増えてきました。特にデータベースのスキーマから自動生成するタイプのものは注目を集めています。AIコーディングに比べると、開発者による差分がない分、こちらの方がチーム開発には向いています。

REST系

PostgRESTは、既存のPostgreSQLデータベースから完全な RESTful APIを生成します。これは、最初から作成するよりもクリーンで標準に準拠した高速なAPIを提供します。
https://postgrest.org/en/v12/

GraphQL系

GraphQLは、柔軟で効率的なデータ取得を可能にするクエリ言語で、特に大規模開発に向いています。Hasuraなどを使用することで、GraphQL APIエンドポイントを自動生成し、迅速に実装できます。
https://hasura.io/

その他の例

個人開発でよく利用されるSupabaseでは、Postgresのスキーマを定義するとREST APIとGraphQL APIを自動生成します。
https://supabase.com/docs/guides/api
https://supabase.com/docs/guides/database/extensions/pg_graphql

また最近発表されたFirebaseのリリースでも、PostgresのデータスキーマからGraphQL interfaceの自動生成がアナウンスされています。
https://firebase.google.com/products/data-connect?hl=ja

他にも、ORMのデータモデル定義から自動生成するものもあります。

CQRSのモダナイズ

DBの進化、バックエンドAPIの自動生成を踏まえると、次のように変化します。

この場合、従来の定義とは異なり、

  • コマンドモデル:バリデーションや、アプリケーションロジックが入り込むバックエンド処理
  • クエリモデル:自動生成ツールによって操作可能なバックエンド処理全般(読み取り、作成、更新、削除のうち単純なもの)

と分けています。単純なCRUD処理(ボイラーテンプレートコードという)→クエリモデル、それ以外→コマンドモデル
と考えるとわかりやすいと思います。

弊社での採用してみて

弊社の開発では、サーバレスデータベースとして、Aurora Serverless v2(クラウド環境がAWSなので)、クエリモデルの自動生成ツールとしてPostGraphileを採用しています。
https://www.graphile.org/postgraphile/

PostGraphileの採用経緯については以下をご覧ください。

https://zenn.dev/ficilcom/articles/invitation-to-postgraphile
https://zenn.dev/ficilcom/articles/graphql-for-saas

採用してみた感想としては、

  • DBをサーバレス化したことで、インフラエンジニアの運用リソースの節約だけでなく、バックエンドエンジニアの認知負荷が下がった。
  • クエリモデルが自動生成されることによって、バックエンドエンジニアはコマンドモデルに集中することができる(サービスにとってよりコアなアプリケーションロジックに集中できる)。
  • データベースモデル=クエリモデルのバックエンドAPIなので、フロントエンドチームとバックエンドチームのコミュニケーションコストが劇的に下がった。

まとめ

モダンCQRSアーキテクチャの設計、現代の要素技術とマッチして少人数でも大規模開発が行えるようになるので、是非導入してみてください。

フィシルコム

Discussion

Naoyuki YamadaNaoyuki Yamada

モダンCQRSモデルとよんでいますが、他の設計パターンの名前がついているかもしれません。知っている方は教えていただきたいです。

Hasuraが提唱している3factor appは近い概念と言えるかと思います。

https://3factor.app/

更新結果をクライアントサイドに戻すためにGraphql Subscriptionを強調していますが、主旨はこの記事でいっていることと近いのかなと思いました。

私も業務で似たアーキテクチャで組んでいます。この記事でよく言語化されていて大変参考になりました。