Go の project layout のやつ

背景

Go で project を作る時に directory 構造をどうするかは議論がある。

公式と非公式の間みたいな資料 (project layout )がずっと参照されていたが、ついに公式からある程度の指針が示された。

Organizing a Go module - The Go Programming Language

短い内容なので、私なりのメモを残す。

内容

package

go で package を作るなら - github.com/someuser/modname という名前にする。 - modname.gopackage modname で書き始める。

すると利用側は

import "github.com/someuser/modname"

と書ける。

Command Line Tool

CLI ツールなどを作る場合は普通に main.go を作り、同様にmodule名を設定する。

利用側は

go install github.com/someuser/modname@latest

と書ける。

大きな Package や依存 package を作る場合

internal/ directory を作って package を区切る。

modname.go で露出していない内部 API は refactor や変更をしやすくなる。

複数 package あっても同様に複数のdirectory を切ればいい

Package と Command が両方入る場合

project-root-directory/
  go.mod
  modname.go
  modname_test.go
  auth/
    auth.go
    auth_test.go
  internal/
    ... internal packages
  cmd/
    prog1/
      main.go
    prog2/
      main.go

auth, internal は import して使われつつ、 progX は go install できる。

Server がある場合

project-root-directory/
  go.mod
  internal/
    auth/
      ...
    metrics/
      ...
    model/
      ...
  cmd/
    api-server/
      main.go
    metrics-analyzer/
      main.go
    ...
  ... the project's other directories with non-Go code

サーバーとして使う場合、export することはあまりないので、internal に logic を全て実装する。

Go 以外のファイルが必要になることも多々あるので、internal 以外のgo ファイルも cmd/ に全て入れる。

感想

ちょうど CobraCLI ツールを作ろうとしていたが、 main.go と同じ階層に cmd/ が自動で作られる点で、この推奨パターンとは少し異なっているかもしれない。

Server を開発する場合に go ファイルをできるだけroot に置かないようにする、というのは次回から取り入れたい。 たしかにroot はよく散らかってしまう。

短かったのでサクッと読めてよかった。