『Microservice APIs』はREST APIとGraphQLの設計に関する入門書レベルの書籍です。
7章あたりにきて、ようやく実装例が出てきますが、「ヘキサゴナルアーキテクチャで実装しましょう」「OrderServiceとOrderRepositoryを作ります」「ドメインオブジェクトとしてOrderを作ります」「Orderのpayメソッドは、Paymentサービスを呼び出します(下記コード参照)」みたいな調子なので、ソフトウェア設計の参考として読むのはやめておいた方がよさそうなスメルがします。あくまでもREST APIやGraphQLを初めて触る人向けの入門書です。
class Order:
# ...
def pay(self):
response = requests.post(
'http://localhost:3001/payments', json={'order_id': self.id}
)
# ...
マイクロサービス
一応、『Microservice APIs』はマイクロサービスのテーマの本でもあるので、そこに言及しているところを深掘りしてみます。
3章ではサービス分割の指針として、以下2通りがあるとされています。
- ビジネスケイパビリティによる分割
- サブドメインによる分割
これ自体は、なんら新しいものでもなく、microservices.ioにて、分割のパターンとして紹介されている2つです。
ここで、よくわからないのが「ビジネスケイパビリティ」というものです。『Microservice APIs』では「事業がどのように組織化しているかを調べ、その組織構造を反映したマイクロサービスを設計する」と説明されており、違和感甚だしいです。
microservices.ioのDecompose by Business Capabilityのページでは、「ビジネスアーキテクチャモデルにおける概念であり、ビジネスが価値を生み出すために行うこと」としています。こんな説明で理解できる人がいるのでしょうか?
『Strategic Monoliths and Microservices』では、そこそこの分量を割いて、そのあたりが説明されています。
『Strategic Monoliths and Microservices』に以下のような一節があります。
サブドメインによって表されるビジネスケイパビリティ概念は、同じ名前の境界づけられたコンテキストで実装される
境界づけられたコンテキストとは、ビジネスケイパビリティのカプセル化であり、各ビジネスケイパビリティは完全な実装を持たなければならない。あるビジネスケイパビリティのいかなる部分も、その境界づけられたコンテキストの外に残されたり、実装されたりしてはならない。
これを図示すると以下のようになると考えられます。
さらには、サブドメインと境界づけられたコンテキストは、mustではないにしろ、洗練されたモデルでは1:1対応し、境界づけられたコンテキストは1つのビジネスケイパビリティを実装する、と述べています。
ということで、ビジネスケイパビリティからのアプローチも、サブドメインからのアプローチも同じことを意味します。そもそも「サブドメインによる分割」というのは問題空間を意味し、全部をソフトウェアで解決するわけではないので、マイクロサービス分割の指針としてはおかしな話です。
ドメイン駆動設計の言葉を使って、マイクロサービスの分割を語るのであれば、
- 境界づけられたコンテキストを出発点として、サービス分割を考えるのは良い。
- だが、正しい境界をはじめから引くことはできないし、「正しい」も移り変わるので、変更に追従できるように設計を考えておく方が重要である。
- 境界づけられたコンテキストのサイズは、ビジネスケイパビリティとそのユビキタス言語の範囲によって制限されるべきである。断じてコードサイズではなく、「マイクロ」を強調すべきではない。
ということになりそうです。