web-dev-qa-db-ja.com

(Golang)クリーンアーキテクチャ-オーケストレーションは誰が行うべきですか?

次の2つのオプションのどちらが適切なアプローチであり、その理由を理解しようとしています。

コントローラーまでWebから呼び出されるGetHotelInfo(hotel_id) AP​​Iがあるとします。

GetHotelInfoのロジックは次のとおりです。

  1. GetHotelPropertyData()を呼び出す(場所、施設…)
  2. 呼び出しGetHotelPrice(hotel_id, dates…)
  3. 呼び出しGetHotelReviews(hotel_id)

すべての結果が返されたら、データを処理してマージし、ホテルのすべての関連データを含む1つのオブジェクトを返します。

オプション1

  • 3つの異なるリポジトリ(HotelPropertyRepo、HotelPriceRepo、HotelReviewsRepo)を作成します。

  • これら3つのリポジトリを使用し、最終結果を返すGetHotelInfoユースケースを作成します。

オプション2

  • 3つの異なるリポジトリ(HotelPropertyRepo、HotelPriceRepo、HotelReviewsRepo)を作成します。

  • 3つの異なるユースケースを作成(GetHotelPropertyDataUseCase、GetHotelPriceUseCase、GetHotelReviewsUseCase)

  • 前の3つのユースケースを調整するGetHotelInfoUseCaseを作成します。 (コントローラになることもありますが、それは別のトピックです)

現在、GetHotelInfoのみがWebに公開されているとしましょう。将来的には、内部リクエストの一部も公開する予定です。

また、GetHotelInfoの実際のロジックが3つのエンドポイントの組み合わせではなく10の場合、答えは異なりますか?

4
Sash

期待されるインタラクター(ユースケースクラス)は他のインタラクターを呼び出します。したがって、どちらのアプローチもクリーンアーキテクチャの原則に従います。

しかし、 "たぶん将来的に"句は、優れた設計およびアーキテクチャの慣例に反します。

再利用を優先できるように、最も抽象的な方法を考えることができます。しかし、常に物事をシンプルに保ち、不必要な複雑さを避けます。

GetHotelInfoの実際のロジックが3つのエンドポイントの組み合わせではなく、10の場合、答えは異なりますか?

いいえ、同じです。ただし、APIを設計しているときに、数十のエンドポイントの組み合わせが必要な場合は、プロジェクトを複雑にするのではなく、GraphQLレイヤーを配置することを検討する必要があります。

2

同様のメソッド(Get()と呼ばれます)は、「 GOを使用したクリーンアーキテクチャ黒田真奈

マナトはそれを指摘している:

  • 次の 非循環依存関係の原則(ADP) の場合、依存関係は円の内側のみを指し、外側を指し示して循環しない。
  • コントローラーとプレゼンターは、特定のロジック(詳細)ではなく、インターフェイスとして定義されているユースケースの入力ポートと出力ポートに依存しています。 依存関係の逆転の原則(DIP) のおかげで、これは(外層の詳細を知らなくても)可能です。

https://miro.medium.com/max/1053/1*mTIKd9Vf0l7Sg7oXhmamQw.jpeg

そのため、例のリポジトリ manakuro/golang-clean-architecture では、Manatoはユースケースのレイヤー3ディレクトリを作成します。

  • リポジトリ、
  • プレゼンター:出力ポート担当
  • インタラクター:入力ポートを担当し、リポジトリーとプレゼンターのインターフェースに応じて、特定のアプリケーションのビジネス・ルールのメソッドのセットを使用します。

その例を使用して、hotel_interactor.goファイルで最初に宣言されたGetHotelInfoを使用し、hotel_repositoryで宣言された特定のビジネスメソッドとhotel_presenterで定義された応答に応じて、ケースを適応させることができます。

2
VonC

クリーンは明確に定義された用語ではありません。むしろ、変更の影響(サービスの追加または削除)を最小限に抑えることを目的とする必要があります。 「影響」とは、コストと時間の要素だけでなく、回帰を導入するリスク(システムの別の部分を壊すことを意図していない)も意味します。

「変更の影響」を最小限に抑えるには、これらを個別のサービス/境界コンテキストに分割し、イベントを通じてのみ対話できるようにします。 「コントローラー」は「ホテル情報リクエスト」などのイベントを(共有バス上で)発生させ、個別のサービス(プロパティ、価格、レビュー)はそれぞれ独立して非同期に(おそらく同じバス上で)応答し、コントローラーは結果を集計してクライアントに返します。これは、一定期間後に行うことができます。結果アグリゲーターを適切にコーディングすると、新しい「機能」を追加したり、他の機能とは完全に独立して既存の機能を削除したりできるようになります。

これを改善するには、各コンテキストの読み取り機能と書き込み機能を独自のコンテキストに分離し、それぞれが適切なイベントに応答します。これにより、読み取り関数とは無関係に書き込み関数を最適化およびスケーリングできます。これをCQRSと呼びます。

1