Go-DDD マーケットプレイスアプリケーション アーキテクチャ¶
このドキュメントは、Go-DDDマーケットプレイスアプリケーションのアーキテクチャを説明するものです。
1. アーキテクチャ概要¶
Go-DDDマーケットプレイスアプリケーションは、ドメイン駆動設計(Domain-Driven Design, DDD)の原則に従って構築されています。アーキテクチャは以下の主要なレイヤーで構成されています:
- ドメインレイヤー: ビジネスロジックとルールを含む
- アプリケーションレイヤー: ユースケースを実装し、ドメインレイヤーを調整する
- インフラストラクチャレイヤー: 永続化やその他の技術的な関心事を処理する
- インターフェースレイヤー: 外部世界とのインタラクションを処理する
これらのレイヤーは、依存関係の方向が内側に向かうように構成されています(オニオンアーキテクチャ)。つまり、内側のレイヤーは外側のレイヤーに依存しません。
2. レイヤー詳細¶
2.1 ドメインレイヤー¶
ドメインレイヤーはアプリケーションの中心であり、ビジネスロジックとルールを含みます。
2.1.1 エンティティ¶
- Product: 商品を表すエンティティ
- Seller: 出品者を表すエンティティ
- ValidatedProduct: バリデーション済みの商品エンティティ
- ValidatedSeller: バリデーション済みの出品者エンティティ
2.1.2 リポジトリインターフェース¶
- ProductRepository: 商品の永続化を担当するインターフェース
- SellerRepository: 出品者の永続化を担当するインターフェース
2.2 アプリケーションレイヤー¶
アプリケーションレイヤーはユースケースを実装し、ドメインレイヤーのオブジェクトを調整します。
2.2.1 サービス¶
- ProductService: 商品関連のユースケースを実装するサービス
- SellerService: 出品者関連のユースケースを実装するサービス
2.2.2 コマンドとクエリ¶
アプリケーションはCQRS(Command Query Responsibility Segregation)パターンを採用しています:
- Command: ドメインの状態を変更する操作(書き込み操作)
- Query: ドメインから情報を取得する操作(読み取り操作)
2.2.3 マッパー¶
- ドメインオブジェクトと外部表現(DTOなど)の間の変換を担当
2.3 インフラストラクチャレイヤー¶
インフラストラクチャレイヤーは、永続化やその他の技術的な関心事を処理します。
2.3.1 データベース実装¶
- PostgreSQL: リポジトリインターフェースのPostgreSQL実装
- GormProductRepository: 商品リポジトリのGORM実装
- GormSellerRepository: 出品者リポジトリのGORM実装
2.4 インターフェースレイヤー¶
インターフェースレイヤーは、外部世界とのインタラクションを処理します。
2.4.1 REST API¶
- ProductController: 商品関連のREST APIエンドポイントを提供
- SellerController: 出品者関連のREST APIエンドポイントを提供
3. 依存関係の流れ¶
依存関係は内側に向かって流れます:
- インターフェースレイヤーはアプリケーションレイヤーに依存
- アプリケーションレイヤーはドメインレイヤーに依存
- インフラストラクチャレイヤーはドメインレイヤーに依存(リポジトリインターフェースを実装)
4. 主要なコンポーネント間の相互作用¶
- REST APIリクエスト処理:
- クライアントがREST APIエンドポイントにリクエストを送信
- コントローラーがリクエストを受け取り、適切なアプリケーションサービスメソッドを呼び出す
- アプリケーションサービスがドメインオブジェクトとリポジトリを使用して操作を実行
-
結果がコントローラーに返され、クライアントにレスポンスが送信される
-
商品作成フロー:
- クライアントが商品作成リクエストを送信
- ProductControllerがリクエストを受け取り、ProductServiceのCreateメソッドを呼び出す
- ProductServiceが商品エンティティを作成し、バリデーションを実行
- ProductServiceがProductRepositoryを使用して商品を保存
-
結果がクライアントに返される
-
出品者更新フロー:
- クライアントが出品者更新リクエストを送信
- SellerControllerがリクエストを受け取り、SellerServiceのUpdateメソッドを呼び出す
- SellerServiceが出品者エンティティを取得し、更新し、バリデーションを実行
- SellerServiceがSellerRepositoryを使用して出品者を保存
-
結果がクライアントに返される
-
商品一覧取得フロー:
- クライアントが商品一覧取得リクエストを送信
- ProductControllerがリクエストを受け取り、ProductServiceのFindAllメソッドを呼び出す
- ProductServiceがProductRepositoryを使用して全商品を取得
-
結果がクライアントに返される
-
商品詳細取得フロー:
- クライアントが商品詳細取得リクエストを送信
- ProductControllerがリクエストを受け取り、ProductServiceのByIdメソッドを呼び出す
- ProductServiceがProductRepositoryを使用して指定IDの商品を取得
-
結果がクライアントに返される
-
商品更新フロー:
- クライアントが商品更新リクエストを送信
- ProductControllerがリクエストを受け取り、ProductServiceのUpdateメソッドを呼び出す
- ProductServiceが商品エンティティを取得し、更新し、バリデーションを実行
- ProductServiceがProductRepositoryを使用して商品を更新
-
結果がクライアントに返される
-
出品者作成フロー:
- クライアントが出品者作成リクエストを送信
- SellerControllerがリクエストを受け取り、SellerServiceのCreateメソッドを呼び出す
- SellerServiceが出品者エンティティを作成し、バリデーションを実行
- SellerServiceがSellerRepositoryを使用して出品者を保存
-
結果がクライアントに返される
-
出品者一覧取得フロー:
- クライアントが出品者一覧取得リクエストを送信
- SellerControllerがリクエストを受け取り、SellerServiceのFindAllメソッドを呼び出す
- SellerServiceがSellerRepositoryを使用して全出品者を取得
-
結果がクライアントに返される
-
出品者詳細取得フロー:
- クライアントが出品者詳細取得リクエストを送信
- SellerControllerがリクエストを受け取り、SellerServiceのByIdメソッドを呼び出す
- SellerServiceがSellerRepositoryを使用して指定IDの出品者を取得
-
結果がクライアントに返される
-
出品者削除フロー:
- クライアントが出品者削除リクエストを送信
- SellerControllerがリクエストを受け取り、SellerServiceのDeleteメソッドを呼び出す
- SellerServiceが出品者エンティティを取得し、削除を実行
- SellerServiceがSellerRepositoryを使用して出品者を削除
-
結果がクライアントに返される
-
JWT認証フロー:
-
ログインフロー:
- クライアントがログインリクエストを送信
- AuthControllerがリクエストを受け取り、UserServiceの認証メソッドを呼び出す
- UserServiceがユーザー情報を検証し、認証結果を返す
- 認証成功時、AuthControllerがJWTトークンを生成してクライアントに返す
-
保護されたリソースへのアクセスフロー:
- クライアントが保護されたリソースにリクエストを送信(Authorization: Bearer
ヘッダー付き) - JWTミドルウェアがトークンを検証(署名と有効期限)
- トークンが有効な場合、リクエストが処理され、結果がクライアントに返される
- トークンが無効な場合、401 Unauthorizedエラーが返される
- クライアントが保護されたリソースにリクエストを送信(Authorization: Bearer
JWT認証は以下の役割を担います:
- ユーザー認証: ユーザーのログイン情報を検証し、有効な認証トークンを発行します。
- アクセス制御: 保護されたリソースへのアクセスを制限し、認証されたユーザーのみがアクセスできるようにします。
- ステートレス認証: サーバー側でセッション状態を保持せず、トークン自体に必要な情報を含めることでステートレスな認証を実現します。
- クロスドメイン認証: 異なるドメイン間でも認証情報を安全に共有できます。