AWS Summit Online – セッション 「ヘキサゴナルアーキテクチャを利用したLambda関数のドメインモデルの実装Live (DEV-09)」を視聴した際の覚書

AWS
AWS
この記事は約3分で読めます。
  • Lambdaでドメインモデルをどのように実装すれば良いか
    • マイクロサービスをLambdaで実装したいが、DDDも活用したい
    • 外部の知識を持たせない
  • Lambdaでユニットテストは難しい?
    • AWS環境にデプロイする前にLambdaをテストしたい
    • ユニットテストが容易な構造にする
  • 他のAWSサービスと連携する必要があるが、ドメインモデルはクリーンに保ちたい
    • ヘキサゴナルアーキテクチャを利用してドメインロジックと外部サービスの間を疎結合に保つ
  • ドメインモデルをクリーンに保ち、単体テストを容易にするサンプルコード
    • https://github.com/aws-samples/aws-lambda-domain-model-sample/blob/main/README.ja.md
  • ドメイン駆動設計とは?
    • DDD
    • エキスパートと開発者が一緒になってモデルを作る
    • モデルの中で共通言語(ユビキタス言語)でモデリングを行い、モデルと実装が常に連動しているスタイルで開発を行う
    • モデルは1回作って終わりでなく、ドメイン理解が進むにつれてモデルが洗練され、コードも進化する
    • ドメインモデルは、レイヤ化アーキテクチャなどによって、インフラコード(DB接続やメール送信するコード)とは分離されている
    • マイクロサービスで使えそう
  • ヘキサゴナルアーキテクチャ
    • ポートとアダプタアーキテクチャ
    • 環境間で疎結合に結ばれるソフトウェア設計のアーキテクチャパターン
    • ドメインモデルを例にすると、中央にドメインモデルがあり、その周りにまずポート、次にアダプタがある
    • 内側の知識と外側の知識を区別する
    • アプリケーションはポートによって接続される
    • ドメインモデルは変更せず、ポートやアダプターによって外部と接続する
    • プライマリアクター
      • ユーザー側
      • 外部から接続される
    • セカンダリアクター
      • DB側
      • こちらから接続しようとする
    • ポート
      • インターフェースのようなもの
      • ユーザー側のポートと、DB側のポートの2種類
    • アダプター
      • プロトコルを変換してポートに渡す
      • またはその逆で、ポートから受け取ってプロトコルを変換し、DBと接続
  • サンプルプログラム
    • ワクチン予約システム
    • ドメインモデルにはサービスにアクセスしたりする外部の知識は持たず、ドメインモデルのみのピュアなロジックを持つ
    • ポートクラス(from Primary)
    • アダプタ(from Primary)
      • Lambdaがその役割
    • ポートクラス(To Secondary)
    • アダプタクラス(To Secondary)
      • 例えばDynamoDBへのアクセスを実装
  • ユニットテスト
    • 手動テストは極力減らす
    • ドメインモデルクラスに対するユニットテストは簡単
      • 業務を表してくれるのが良い
      • ユニットテストは日本語で書くと分かりやすく、良い
        • どこの業務が間違っているか見てすぐに分かる
      • ストレージがDynamoDBからRDSに変わったとしても、ビジネスロジックを変えなくていい(アダプタがよしなにやってくれる)
    • main.pyにより擬似的にLambdaハンドラーを再現
      • Lambdaデプロイ前でも、テストが可能
      • 渡すアダプターを変更することにより、AWSリソースに接続しないテストも、ダミーデータによるテストも、AWSリソースに接続するテストも行える
      • 便利
    • ピュアロジックに対するユニットテスト
      • 純粋な要件(他のAWSサービスとの結合方法に対する知識を含まない)に対してテストケースを書く
      • テストが軽くなり、開発高速化
      • 外部アーキテクチャ変更時も、テストケースが影響を受けにくい
      • 意図が伝わりやすい、理解しやすい
        • テストケースから仕様を理解できる
タイトルとURLをコピーしました