TaNA LABO
エンジニアリング

June 08, 2020

Go
Gin
DDD
アーキテクチャ

Golang+GinでのDDDアーキテクチャ設計 − API設計でのパッケージ構成

post 45

ドメイン駆動設計入門にて 概念を実装に落とし込むパターン を確認し、Goのアーキテクチャ構成を調査すると レイヤードアーキテクチャ + DDD を解説される方が多かったので、簡単にまとめてみた。

まず 「Go DDD」 で検索すると、検索一覧のトップに コチラの記事 が表示される。図解で丁寧に説明され githubにサンプルコード も用意されているので、最初に読む記事としては良いかも。

.
├── cmd
│   └── api
│       └── main.go
├── domain                      # エンティティや値オブジェクトなど(構造体定義)
│   └── repository              # インターフェースのみ(実装はinfrastructure層)
|   |   └── user_repository.go
|   └── user.go
├── config
│   └── database.go
├── interfaces                  # FWのコントローラクラス(リクエスト/レスポンス処理)
│   └── handler
│   |   └── user.go
|   └── response
│       └── response.go
├── infrastructure              # DBアクセスなど技術的関心 / DIP(-> domain層)
│   └── persistence
│       └── user.go
└── usecase                     # interface層から銃砲を受け、domain層の関数利用
    └── user.go                 # DDDでのアプリケーションサービス

Web上では色んな方が解説されており、レイヤードアーキテクチャなので インターフェース / ドメイン / インフラストラクチャ / アプリケーション(ユースケース) の4つの階層(ディレクトリ)は必ず用意。その他フォルダはお好みで自作しているイメージかな。

しかし何となくレイヤードアーキテクチャのディレクトリを用意し、レイヤを切り分ければ良いのではなく DIP(依存関係逆転の原則) 適用するために、interfaceで抽象の公開に注力することが大切だと リクルートライフスタイル さんの記事でも紹介されていた。

Goのpackage構成と開発のベタープラクティス

上記リンク先の記事では、フレームワーク等を利用しない単純な構成で、package構成の意図やインターフェースの実装例があり、個人的にはこの構成が一番しっくりくる。

ちなみにリクルート記事内でGunosyのパッケージ構成もあった(変遷が面白い)

Goのパッケージ構成の失敗遍歴と現状確認

.
├── application                    # レイヤードアーキテクチャでのapplication層
│   └── usecase                    # DDDでのアプリケーションサービスを配置
│       ├── xxx_usecase.go
│       └── yyy_usecase.go
├── domain                         # レイヤードアーキテクチャでのdomain層
│   ├── model                      # DDDでのエンティティ/値オブジェクト
│   ├── repository                 # DDDでのリポジトリ
│   │   └── xxx_repository.go      # interfaceのみ定義(実装はinfrastructure層)
│   └── service                    # DDDでのドメインサービス
├── infrastructure                 # レイヤードアーキテクチャでのinfrastructure層
│   └── persistence                # 永続化の実装方式に応じてサブパッケージを切る
│       └── datastore              # データベース接続を想定
│           └── xxx_repository.go
├── interfaces                     # レイヤードアーキテクチャでのUI層
│   └── api                        # httpを想定(標準出力等は別パッケージを切る)
│       └── server
│           ├── auth
│           ├── handler
│           │   ├── app_handler.go
│           │   ├── xxx_handler.go
│           │   └── yyy_handler.go
│           ├── httputils
│           ├── middleware
│           └── router
└── registry                       # DI解決のためのオブジェクト生成ルール
    └── registry.go

また IIJ さんの記事では DDD + クリーンアーキテクチャ のアーキテクチャを紹介されているが、構成がほぼほぼ同じなので、多くの有識者の方に支持されるアーキテクチャかもしれない(業務でここまで綺麗な構成のシステムに出会った事がないので、使用感は何とも言えないけど・・・)

go言語でクリーンアーキテクチャっぽいもの

リクルートさんの記事以上に、図解で丁寧に説明されており、各レイヤ間の依存関係や役割が可視化されて理解しやすい。昨今クラウド環境の発達で、技術の選択肢も増えているので、handler(httpsとpubsub等)やpersistence(RDBSとNoSQL等)のサブディレクトリを切るのが良さげ。

ちなみにタイトルではGolang+Ginにしてますが、本記事ではGin全く関係ないっすmm

その他参考記事

Golang + レイヤードアーキテクチャ - DDDを意識してWebAPIを実装してみる


©Copyright2020 TaNA LABO. All Rights Reserved.