アプリケーションアーキテクチャ設計に関する覚書(Go)
1. 前提条件
2. 基本的な考え方
3. プロジェクト構造
4. src以下の構造
ディレクトリ構造
src/
├─ config/
├─ handler/
├─ lib/
├─ mock/
├─ model/
├─ repository/
├─ usecase/
├─ validator/
└─ main.go
config
- アプリケーションの設定を管理
- 典型的にはconfig/config.goだけが配置される
package config
type Config struct {
...
}
handler
- MVCにおけるコントローラ
- HTTPリクエストの受信とレスポンスの返却を担当する
- HTTPリクエストに関する処理はこのレイヤーで完結させ、これ以降のレイヤーに影響させてはいけない
lib
mock
- ユニットテストで使用するモックを配置する
- 典型的にはgo-mockで生成したモックが配置される
model
- ドメインオブジェクトを配置する
-
controller
で使用するリクエスト/レスポンスデータの構造体もここに配置する
repository
- データアクセスを抽象化するレイヤー
- DBアクセスや外部APIアクセスを実行するモジュールが配置される
usecase
- ドメインモデルを用いたビジネスロジックが記述されるレイヤー
-
controller
から呼び出される
-
usecase
に属するモジュールは以下の規則に従う必要がある
type ShowExampleList interface {
Execute() error
}
type showExampleList struct {
...
}
func (u *showExampleList) Execute() error {
...
}
- (1) ひとつのユースケースを表現する
- 更にこれらのユースケースはファクトリーによってパッケージ外部に公開される
type Usecases interface {
ShowExampleList() ShowExampleList
ShowExampleDetail() ShowExampleDetail
}
type usecases struct {
...
}
func NewUsecases() Usecases {
return &usecases{}
}
func (u *usecases) ShowExampleList() ShowExampleList {
return &showExampleList{}
}
func (u *usecases) ShowExampleDetail() ShowExampleDetail {
return &ShowExampleDetail{}
}
validator
- ドメインルールのバリデーションを行うモジュールが配置される
- modelの中に含めてもよいかもしれない
-
handler
で行うバリデーションはフォーマットチェックで、usecase
で実行されるドメインルールに対するバリデーションを行う
- 例えば、DBにアクセスしてデータの存在チェックを行ったりするかもしれない
main.go
- プログラムのエントリーポイント
- 必要に応じて
cmd
ディレクトリを作成し、その中でserver
用cli
用のmain.go
を作成してもよい
5. ファクトリーとinterface
- テストを容易にする為に別レイヤーから呼び出されるモジュールは
interface
を定義する
- 具体的には
usecase
とrepository
は必ずinterface
を定義する
usecase
packcage
- このようにしておくことでモック化しやすくすることができ、ユニットテストが容易になる
- 典型的な
Abstract Factory
パターンである
6. 各レイヤーのユニットテスト
repository