シリーズGosenbonKnockでは会社でGo入門用に起こしたテキストを適度にコピーして公開していきます。
パッケージ内のディレクトリはどう構成すべきか
1. srcディレクトリを内部に作るべきか否か
java等ではアプリケーションのトップレベルディレクトリ配下にsrcディレクトリがあり、その下にパッケージ等が展開されていく事が多いため、srcの下からmain.goを始めることが多いのですがGoではsrcディレクトリは基本的に作らないことのほうが多いように思います。
- すでにアプリケーションを${GOPATH}/srcに配置して開発する
- パッケージ配下にsrcディレクトリを持つと、「import時に(パッケージ名)/src/サブパッケージ名 」となるため冗長になる
- そもそもsrcがあっても出力ディレクトリが必要なく、go buildを行ったときには行った場所にバイナリが生成される など、作ってもあんまり意味ないよねという風潮に思います(個人の感想です)
ディレクトリ構成案
Web/CLI、利用するフレームワークなど、依存する部分は多々ありますが、たとえばWebアプリケーションの場合以下のような構成になるのではないでしょうか
※ イメージしやすいように一部CleanArchitectureの概念に沿って記載しています
dirsample
├── controllers // 処理ハンドラを格納する
│ ├── search //オペレーション指向で定義するとき
│ │ └── operation.go
│ └── users //リソース指向で定義するとき
│ └── resource.go
├── entities // ユースケース上やり取りされるデータ構造を表すstruct等を格納
│ ├── searchresult
│ │ └── entity.go
│ └── user
│ └── entity.go
├── main.go
├── middlewares
│ └── databases
│ └── middleware.go
├── presenters
│ ├── search
│ │ └── view.go
│ └── user
│ └── view.go
└── usecases // ビジネスロジック・ユースケースプロセスを格納
├── search
│ └── usercase.go
└── users
└── usecase.go
【あとで検証します】ライブラリ作成時における、自パッケージ内へのimport記述について
sample
├── usecase
│ └── filesearch
│ └── usecase.go
└── lib.go
このとき、lib.goから内部に定義したsample/usecase/filesearchパッケージを利用する際のimport記述は以下の様になります
import(
"usecase/filesearch"
)
ここで、ライブラリを開発し公開した場合を考えてみましょう。
公開したライブラリを利用したいユーザーの人は、このライブラリをgo getあるいはglide get(あるいはdepかもしれませんが)で取得してきます。
githubに公開しているライブラリであれば
go get github.com/{あなたのユーザーID}/sample
となるわけです。
そうすると${GOPATH}/src配下(glide, depで取得した場合はvendor/配下)は以下のようなディレクトリ構成になります
~/go/src($GOPATH}が$HOME/goの場合)
└── github.com
└── {あなたのユーザーID}
└── sample
└── filesearch
このときに、利用ユーザーがsample/lib.goに記載された処理を利用しようとすると、lib.go内では"usecase/filesearch"としてimportしているためコンパイル時に
go/src/usecase/filesearch
を走査しに行ってしまい、実際には
go/src/github.com/{ユーザー名}/sample/usecase/filesearch
にあるソースを読みに行く場所を間違えてしまうため、コンパイルできない状況が発生してしまいます。※自信なくなってきたのであとで検証します
つまり、ライブラリ開発の場合は、 開発中のパス 公開するパス
を正しく合わせた状態で開発する必要がありますので、注意する必要があります。