Golangのディレクトリ構造について学んだことを書く。
Golangの専門用語
専門用語を正しく使うことが良いプログラマーへの第一歩だと思った。
モジュールとパッケージ
https://go.dev/ref/mod#modules-overview
モジュールはパッケージの集まりで、バージョンコントロールされてリリースされている単位。リポジトリから落としてくるのはモジュールということ。
パッケージはモジュールの中にあり、同じディレクトリの中にあって一緒にコンパイルされるソースコードファイルの集まり。関数は定義されたパッケージの中であれば自由に呼び出せるが、外からは呼び出せず、外から利用させるためには関数を大文字にする必要がある。
Golangのディレクトリ構造
ドキュメントはこちら。モジュール内の構造について書かれている。
https://go.dev/doc/modules/layout
Basic package
最も基本的な構造。プロジェクトのルートディレクトリにすべてのファイルが存在する形。
Basic command
commandとは実行可能なプログラムのこと。コマンドラインツールとかWebアプリケーションとかとにかく実行可能ならcommand。
commandにするにはmain()関数が必要なので、main関数が存在してすべてのファイルがルートディレクトリにある構造をBasic command構造という。まぁBasic packageとさほど変わらん。
Package or command with supporting packages
commandはコードが大きくなりがちで、Basicのままだと見通しが悪くなる。そこで機能的にパッケージを分けていくと良い。
internalパッケージを使えば、これは同じモジュールからしか呼び出せない(たとえ関数名が大文字でも別のモジュールからは隠蔽される)ので、外部のことを気にしないでよくなる。
- project-root/
- internal/
- auth/
- hash/
- main.go
- internal/
Multiple packages
パッケージは複数個切っても良いよということ。スキップ。
Multiple commands
commandが複数個ある形。
- project-root/
- internal/
- prog1/
- main.go
- prog2/
- main.go
こんな感じにすると良い。internal以外にももっとパッケージを切りたい時は、意味を分かりやすくするためにcmdパッケージにcommandたちを入れるとなお良い。
- project-root/
- cmd
- prog1
- main.go
- prog2
- main.go
- prog1
- cmd
特に、サーバーアプリケーションの場合はプログラム以外にもファイルが多いのでこの形が好まれる。
go.mod と go.sum
Goプロジェクトには必ずあるファイルたち。
go.modはモジュールの情報を管理している。例えばこのモジュール名・モジュールの依存モジュール(間接も)とそのバージョンなど。
go.sumはgo mod tidyをした際に生成されるファイルで、モジュールのハッシュを記録している。
これにより、例えばCIでgo.modを元にモジュールをダウンロードした際に、それぞれのモジュールのハッシュ結果が以前にgo.sumを作成した際のハッシュ結果と一致しているかを調べることができる。
これにより、同じバージョンをダウンロードしたのに中身が変わっているというセキュリティ的に怪しい状況に気づくことができる。
終わりに
Goのディレクトリについて調べたよ。
Webアプリケーションを作成する時はとりあえずinternalを切っておけば大丈夫そうに思う。