アプリケーション設計の考え方をマイクロサービスの構成に適用する

# はじめに

私は以前から、マイクロサービスはオブジェクト指向モデルの一種であり、オブジェクト指向プログラミングによるアプリケーションの設計とマイクロサービスの設計には多くの共通点があるのではないかと考えていました。

自分の考えの整理を兼ねて、アプリケーション設計とマイクロサービスの設計についてつらつらと書いていきます。

※ この記事では、マイクロサービスにおける 1 サービスを「アプリケーション」と呼び、1 アプリケーション内の設計を「アプリケーション設計」と呼んでいます。

# レイヤー構成

アプリケーションを実装する際、トップレベルで考えるアーキテクチャは、

* クリーン・アーキテクチャ
* オニオン・アーキテクチャ
* ヘキサゴナル・アーキテクチャ
* レイヤード・アーキテクチャ

といった、レイヤー構成に関するものです。[^1]

[^1]: 「トップレベル」という表現は書籍『.NET のエンタープライズアプリケーション・アーキテクチャ』にあるものです

最近ではクリーン・アーキテクチャを見かけることが多いです。

![CleanArchitecture.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216010/e0b117ed-566a-8f10-f808-94e338fd3bbc.jpeg)

出展: 「[The Clean Architecture](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)」

マイクロサービスのレイヤー構造としては、BFF (Backends For Frontends) というデザインパターンがあります。
以下は、BFF を説明する図です。

![bff-overview.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216010/5f6d655f-b033-010f-f8f4-74aa538666cb.jpeg)

出展: 「[Pattern: Backends For Frontends](https://samnewman.io/patterns/architectural/bff/)」

これら 2 つの図は全然違うように見えるかもしれませんが、実はかなり似ています。

BFF によるマイクロサービスの図を円形にすると、以下のようになります。

![Microservices_CleanArchitecture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216010/35329db1-eb9c-ec10-a809-2b5ce812b84e.png)


クリーン・アーキテクチャの図と見比べると、

* 「クリーン・アーキテクチャにおける Use Cases の層 (アプリケーション層)」と「マイクロサービスにおける BFF の層」
* 「クリーン・アーキテクチャにおける Entities の層 (ドメイン層)」と「マイクロサービスにおける Downstream Services の層」

が、それぞれ対応するように見えます。

これらの対応について、もう少し考えてみます。

# アプリケーション層

クリーンアーキテクチャの図で Use Cases と書かれた層は、アプリケーション層とも呼ばれます。
この層の責務は、ドメインモデルのインターフェースを利用してユースケースを実現することや、トランザクションなどのアプリケーション都合のロジックを実現することです。

マイクロサービスにおける BFF は、マイクロサービス全体におけるアプリケーション層の役割を果たします。
BFF は、アプリケーションにおけるアプリケーション層と同様、背後にあるコアなドメインの API をファサードし、ユースケースを実現するのです。

マイクロサービスにおけるトランザクション管理では Saga というデザインパターンが有名ですが、その Orchestration 型の実装も、「アプリケーション層がトランザクションを実現する」と近いものを感じます。

参考
[マイクロサービスの Saga パターンについて](https://qiita.com/yasuabe2613/items/b0c92ab8c45d80318420)

# ドメイン層

## マイクロサービスとオブジェクト指向

アプリケーションにおいて、ドメインモデルはデータ (フィールド) を隠蔽して外部に振る舞い (メソッド) を提供するオブジェクトとして実装されます。
データを隠蔽して外部に振る舞いを提供するというのは、オブジェクト指向のコアな考え方です。

マイクロサービスにおいてアプリケーション間でデータベースを共有することは避けるべきとされており、データ (データベース) を隠蔽して振る舞い (API) を提供するというのは、まさにオブジェクト指向です。

マイクロサービスにおいて共有データベースはアンチパターンと言われますが、これは「オブジェクト指向的な設計」という観点からも当然のことなのです。

## 永続化の単位 - 集約

ドメインモデルにおいて、データの永続化は「集約 (Aggregate)」という単位で扱います。
「集約」をマイクロサービス的に言うと、「1 アプリケーション」に相当するのではないでしょうか。

アプリケーション設計の文脈では、集約をまたがる永続化について、オブザーバーパターンを適用するなどして疎結合な実装にする場合があります。
マイクロサービスをまたがる処理についても、キューなどを利用して疎結合に実装する場合があります。

参考
[やはりお前たちのRepositoryは間違っている](https://qiita.com/mikesorae/items/ff8192fb9cf106262dbf)
[DDD実践(ベスト)プラクティス｛ドメインイベントとマイクロサービスと組織の関係｝](http://qcontokyo.com/data_2016/pdf/B-2_2_JunichiKato.pdf)
[実践ドメイン駆動設計](https://www.amazon.co.jp/dp/479813161X)

# おわりに

なんとなく「マイクロサービスと OOP の設計は共通点が多そうだな」と感じたことをつらつらと書いてみました。
(これだけの内容ではどう活かせるのかもはっきりしませんが...)

考えてみれば当たり前の話ではありますが、マイクロサービスにオブジェクト指向の原則を適用するという記事もいくつかありました。

* 「[To address microservices issues, turn to OOP principles](https://searchapparchitecture.techtarget.com/tip/To-address-microservices-issues-turn-to-OOP-principles)」
* 「[Microservices and objects: Similar benefits, similar problems, similar lessons?](https://blog.container-solutions.com/microservices-objects-similar-benefits-similar-problems)」
* 「[Why Object Oriented Code Accelerates Microservices Adoption](http://mfadhel.com/object-oriented-microservices-migrations/)」

以上、何の役に立つかも分からないポエムでした。