レイヤードアーキテクチャとCQRSの導入事例

イラスト:記事タイトルと開発メンバー、著者の三島だけ色が塗られている

こんにちは開発室の三島です。 最近スキーに行きたい気持ちが高まっています。

この記事は「エディトルブログキャンペーン」2日目の記事です。昨日の記事はフロントエンドエンジニアの小澤による「フロントエンド街道爆進中!」でした。

私は新卒で2016年に入社し2019年5月までメディアサイトの開発に携わってきました。 その後、新規サービスのエディトル開発チームへ2019年6月に異動し開発をしています。 この記事ではエディトル開発チームへ異動してからのバックエンドアーキテクチャの変化について書きます。

はじめに

開発当時の設計は、レイヤードアーキテクチャを採用し、ドメイン知識をドメイン層に閉じ込めることでビジネスの関心事とシステムの関心事を分離する設計になっていました。 レイヤードアーキテクチャを採用することで利点もありましたが同時に辛みもありました。つらみを解消する取り組みとしてアーキテクチャの一部変更をしました。その結果を共有します。

変更前アーキテクチャ概要

f:id:MikaE:20200207142143j:plain

エディトルのアーキテクチャは上図のような設計になっています。 大きく分けると、「Application Layer」「Domain Layer」「Infrastructure Layer」の3つのレイヤーに分けられます。 それぞれの役割は、

  • Application Layer
    • リクエストを処理し、データの取得や更新の指示
    • データの変換処理
  • Domain Layer
    • ビジネスの関心事を処理
    • 税金計算や記事の表現
  • Infrastructure Layer
    • 外部との接続
    • システムの関心事を処理

となっています。

レイヤードアーキテクチャを使い開発を進めていく中で良かった点としては、コードを記述する場所が明確になることです。 適切に関心事の分離ができていれば、変更や新規機能追加に強いシステムになります。

ただ、開発を進める中でいくつか辛みが出てきました。 初期の設計では各レイヤー間のデータのやり取りはすべてDomain LayerのEntityに変換し渡す必要がありました。 レスポンスを返すためにEntityを取得しApplication Layerでレスポンス形式に毎回変換する処理を記述していました。 データを取得し変換するだけの単純な処理でもファイルの変更や追加する箇所が多くなっていました。 また、読み込みと書き込みで同じEntityを使っていたため、ファイルの変更による影響範囲も機能の増加とともに複雑になっていました。

エディトルのドメイン設計にも問題がありました。 問題点としては、開発を担当する人が、レイヤードアーキテクチャにおけるドメインの設計を理解していませんでした。そのため、レスポンス形式に依存したドメインやデータベースに依存したドメインが作られていました。

変更後のアーキテクチャ概要

異動後アーキテクチャの一部変更と、チームメンバーへレイヤードアーキテクチャの設計理解について勉強会を開催しました。 その中でもアーキテクチャの一部変更を実施し開発スピードが上がったので共有します。

前述するとおり設計に関して色々な問題がありました。 データの変更と取得を1つのEntityで表現しようとし無理が出てきていました。 その結果を受け、CQRSを導入し、コマンドとクエリの分離を導入しました。 CQRSとはコマンド クエリ責務分離パターンです。コマンドには副作用のある処理、クエリにはデータを習得する処理を記述します。 詳しくは参照のリンクを読んでいただけるとわかるかと思います。

docs.microsoft.com

https://cqrs.files.wordpress.com/2010/11/cqrs_documents.pdf

CQRSを導入することで以下のような設計に変更しました。

f:id:MikaE:20200207150157j:plain

副作用のある処理はDomainを通し処理し、直接データを習得するだけの処理であればQueryを通すようにしました。

変更後の振り返り

CQRSを導入することでReadをするだけのAPIの場合、変更前は作成に2日以上かかっていたのが、半日に短縮できました。 UpdateやCreateのAPIの場合でも変更前は作成に3日以上かかっていたのが、2日に短縮できました。 Query層を作ることによりコードの役割が明確になり、ファイルの変更追加のコストが下がりました。

今後の展望

2019年はアーキテクチャを変更することでサービスの成長に合わせて成長できるシステムを目指し開発を進めてきました。 ある程度は高速開発を実現できましたがまだまだ課題はあります。 今課題となっていることはAPI定義の仕様のズレや要件漏れなどWeb側との連携コストです。 今後は連携コストを下げていけるような取り組みをします。

明日はエディトルのフロントエンド、バックエンド開発や事業部との調整を担当している垣花で「フロントエンド、バックエンドの架け橋〜その仕事私が調整します」です。

乞うご期待!