見出し画像

マイクロサービス用のアーキテクチャについて考えてみる

はじめに

自分自身今までアーキテクチャにはかなりこだわりを持って考えてきました。MVCから始まってファットコントローラーの解消を目指したMCSC、さらに分離したクリーンアーキテクチャ。実際にクリーンアーキテクチャを自分なりに考えたりしてやってきましたが少し欠点などが見つかってきました。

今回はいくつかの前提を持った上でヘキサゴナルアーキテクチャについて考えていきたいと思います。ただどうしても作るとなると長くなってしまうのでこの記事では参考になりそうなリポジトリや記事のみを集めて次の記事で実際に組んでみたいと思います。

ある程度ヘキサゴナルアーキテクチャについて理解していて自分のメモのような感じになっています。記事をみる際はリンク集程度に思ってください。

前提

Goを使用する

ヘキサゴナルアーキテクチャであること
- テストのしやすさだったりモックの作りやすさに注意を払いたい
- ポート周りは意識しておきたい

マイクロサービスのサービスの一つ
- データベースは一つ
- モデルも一つ
- gRPCを使うこと

クリーンアーキテクチャよりシンプルなものにしたい
- みたときに理解しやすいものにしたい
- できるだけアーキテクチャの図内に出てくる名前でフォルダを命名したい
- 複雑にネストされたディレクトリ構造はやめたい

調査内容

今回具体的に調べたいものは以下です。

  1. 各パーツの名前はどのように再現するのか

  2. ポートやアダブターとは何か?コード上ではどのようになるのか

です。

参考記事

1. Hexagonal Architecture in Go

この記事では一番真ん中をCoreと呼んでいるみたいです。Actorsは分類としてはprimaryとsecondary。Actorsとアダブターを分けていますがこの記事のActorsとアダブターを合わせたものがアダブターで良い気がしています。
ポート:actorとcore間のコミュニケーションについて定義したインターフェース
ポートは特性によって2種類に分けられる
primaryに対するポート:コアが外部に提供する関数を提供
secondaryに対するポート:actorが実装しなければならない関数

この例が結構特殊で全ての処理で必ずしもDBを必要としていないと言った理由でドメイン層にも多少ロジックが置かれています。core部にコードが偏っている気はしますが結構シンプルにできている気がします!このServicesがどこパーツとして扱われているのかがわからなかったです。これもコアか?

2. Hexagonal Architecture in Go

先ほどのと記事の名前は同じですが別の記事です。

core/infrastructure/gateway.goがあまりわからないです。これどことどこのゲートウェイになっているんですかね?説明やコードをみた感じドメインとアダブター(今回はHTTP)の間に立っているものだと思うのですがこの場合HTTP以外のCLIとかとして実装したい場合同じインターフェースを定義することになる気がします。またstorageがドメインと実際のデータベースの間に立っているものだとは思います。
ただ今回の自分の要件のようにgRPCで繋ぐこと前提なのであればわざわざインターフェースだけのファイルを作らずにインターフェースと実装を一つにまとめるのはありだと感じました。

3. Hexagonal Architecture with Go and Google Wire

ドメイン部が結構シンプルになったパターンでドメインには必要なインターフェースを定義していています。ドメインに関わってフレームワークには依存しないコードについてはサービスという形表しているみたいです。結構擬似的にハンドラー・ユースケースみたいな形を撮っているように見えます。
ドメイン部が個人的に綺麗に感じました。

ここまでの感想

ここまでみてきたのですがコアの中にどこまでロジックを入れたいかによってだいぶディレクトリ構造が変わってくるような印象を受けました。本当にモデル定義とインターフェース類だけにしたいのかそれともサービス(アダブターによらず書き出した共通処理)を入れるのか。またそもそもサービスという層を入れるのかによっても結構変わってくる気がしました。

恐ろしく雑な絵で申し訳ないのですが以下のようなイメージで作ろうと思いました。

コア部にドメインとサービス(データベースやアダブターに関係なく行う処理)を実装。サービスに関しては外部から接続できるようにポートとして公開し、プライマリーサービスが使えるようにする。サービスが使うセカンダリーポートに関してはこれもポートで実装を受け付けてサービス内で使用と言った感じです。依存関係に関してもDIさえすれば外のものが内に依存する形が取れるので大丈夫だとは思っています!

考える上でのポイント

具体的なディレクトリ構造に関しては別の記事で考えますがいくつかポイントとなりそうな箇所があるのでまとめておきます。

サービスやポートはCore部に含む

そもそもコア部に含まないと中のコードが外に依存してしまう状態になる気がします。なのでコアにはモデルとサービス・各種ポートが必要になってくる気がします。


この記事が気に入ったらサポートをしてみませんか?