LoginSignup
0
0

More than 3 years have passed since last update.

ワイ的Goのプロジェクトのパッケージ割りはこれだ

Posted at

はじめに

goのパッケージ割りって悩みますよね。。
githubにもデフォルトのパッケージ割りが公開されていますが、webにそのまま使える訳でも無く、いろんな記事を見て実際に落とし込んだワイ的ベスト(現段階)パッケージ割りを紹介します!
(増田さんも「goはDDDに向かない」と仰っていましたね。。w)

TIDL(長くは無いけど)

.
├── Dockerfile
├── Makefile
├── README.md
├── bin //プロジェクトで使うバイナリ(wireとか)
├── cmd //エントリポイント
│   ├── app
│   │   ├── main.go
│   │   ├── wire.go
│   │   └── wire_gen.go
│   └── batch
│       ├── main.go
│       ├── wire.go
│       └── wire_gen.go
├── config.yaml
├── docker-compose.yaml
├── docs // ドキュメント(swaggerとか)
├── go.mod
├── go.sum
├── migrations // migrationファイル
├── pkg
│   ├── adaptor
│   │   ├── api //コントローラなどi/o(adaptor層)
│   │   │   ├── converter //i/o変換
│   │   │   ├── input //iで飛んでくるパラメータやbodyのstruct
│   │   │   ├── middleware // middleware(認証など)
│   │   ├── infrastructure
│   │   │   ├── client //APIクライアント
│   │   │   ├── dto //dto
│   │   │   └── repository //repository実装
│   │   └── logger // logger
│   ├── application //application層
│   │   ├── scenario //シナリオクラス
│   │   └── service //アプリケーションサービス
│   ├── config // config struct
│   ├── domain // domain層
│   │   ├── entity //entity
│   │   ├── factory //factoryクラス
│   │   ├── model //domain model
│   │   ├── repository // repository interface
│   │   └── service // domain service
│   ├── mock // mock(テスト用)
│   └── util //utilクラス
├── scripts //1度きりの実行スクリプト(データのimportとかに使ってます)
└── tools //module使ってるので消えない様に

bin

プロジェクトでwireだったりairだったり使うもののバイナリを置いておきます。
これでバージョン統一ができたりします。
ちなみにtoolsパッケージで定義しておきます。
https://tchssk.hatenablog.com/entry/2018/12/22/000000

cmd

goのデフォルトでもエントリポイントとして紹介されています。
プロジェクトの起動を行うmain.goを置いています。
バッチとかもあると思うので自分のプロジェクトではまとめて置いています。(実際使用する時はimageで起動コマンドを分けています)

pkg

外部に公開するパッケージです。
実際に開発する際に主に使用するパッケージです。
ちなみにinternalは外部に公開することができません

adaptor

外界との接着点です。
自分はapi/にコントローラを直置きしています。

converter

外界とアプリケーションのi/oの責務を持ちます。
パラメータやbodyで飛んできた物を変換したり、逆にentityを変換しapiレスポンスとして外界に返します。
inputとoutputパッケージを主に使用します。

input

外界から飛んでくるパラメータやbodyの定義をここで行います。(コントローラでbindして使います。)
例えばこんな感じです。

post.go
package input

type Post struct {
  Title string `json:title`
  Body  string `json:body`
]

output

inputと同じ様にアプリケーションから外界に出ていく型を定義します。

middleware

middlewareを置きます。

infrastructure

外界との接着点で主にDBやAPIの処理を行います。

client

APIクライアントです。repositoryで使います。

dto

clientやrepositoryで使用されるdtoを定義しています。

repository

repositoryの実装クラスです。

logger

loggerですw

application

application層です。
interfaceと実装両方置いています。

scenario

シナリオクラスです。
application serviceもシナリオクラスなのですが、大きく処理が別れることがあればシナリオクラスを挟む様にしています。
シナリオクラスを爆誕させすぎるのはおすすめしないので用法容量を守って使って下さいw

service

application serviceクラスです。
例えば

post_query.go
type (
    PostQueryService interface {
        ShowPost(id int) (*entity.post, error)
    }

    PostQueryServiceImpl struct {
        Repository repository.PostQueryRepository
    }
)

余談ですが、CQRSに寄せており、controller、service、repositoryは全て_queryと_commandに分かれてます。

config

configクラスです。
どこからのパッケージでも読める様に独自にパッケージ割る様にしています

domain

domai層です
ドメイン層は説明省きます。

mock

モック置いてます。

util

utilクラス

tools

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0