概要

これは、Goアプリケーションプロジェクトの基本的なレイアウトです。これは**Goコア開発チームによって公式に定義された標準ではありません。一般的にGoプロジェクトのディレクトリレイアウトとして使用されている**ものです。

Goを学んでいるか、概念の証明(PoC)を行うか、あるいは単純な個人プロジェクトを構築している場合、このプロジェクトレイアウトは複雑すぎます。その代わりに、本当にシンプルなレイアウト( main.go ファイルと go.mod があれば十分です)から始めてください。 プロジェクトが進化するにつれ、コード構造が適切でないと、隠れた依存関係やグローバルな状態が多く含まれた不整頓なコードになるでしょう。プロジェクトに複数の人が関与するようになると、より構造化された方法が必要となります。この場合、パッケージ/ライブラリを管理する一般的な方法を導入することが重要です。また、オープンソースプロジェクトを持っている場合や他のプロジェクトがあなたのプロジェクトリポジトリからコードをインポートすることを知っている場合、プライベート(またはinternal)パッケージとコードが重要になります。リポジトリをクローンし、必要な部分を保持し、それ以外のすべてを削除してください!存在しているからといって、すべて使用しなければならないわけではありません。これらのパターンはすべてのプロジェクトで使用されるわけではありません。vendorパターンさえ、普遍的ではありません。

このプロジェクトのレイアウトは意図的に非常に一般的なものとして設計されており、特定のGoパッケージ構造を押し付けることはありません。

Goプロジェクトディレクトリ仕様

以下は推奨されるGoプロジェクトディレクトリ仕様です。

.
├── go.mod
├── api
├── assets
├── build
├── cmd
├── configs
├── deployments
├── docs
├── examples
├── githooks
├── go.mod
├── init
├── internal
├── pkg
├── scripts
├── test
├── third_party
├── tools
├── vendor
├── web
└── website

各ディレクトリの意味について以下で紹介します。

/cmd

プロジェクトのメインアプリケーション、つまりプログラムのエントリーポイントです。このディレクトリ内のGoファイルは通常実行可能ファイルを生成します。単純なプロジェクトでは、/cmd/myappのようなファイルがエントリーポイントとして機能します。

各アプリケーションディレクトリのディレクトリ名は、望む実行可能ファイルの名前と一致するべきです(例:/cmd/myapp)。

アプリケーションディレクトリにあまりにも多くのコードを置かないでください。コードを他のプロジェクトにインポートして使用できると考える場合は、/pkgディレクトリに配置してください。コードが再利用できない場合や他の人がそれを再利用しない場合は、コードを/internalディレクトリに配置してください。他の人の行動に驚くことでしょうから、明確に意図を表現してください!

通常、main関数は/internalおよび/pkgディレクトリからコードをインポートして呼び出す小さな関数のみを含み、それ以外は何も含みません。

/internal

プライベートアプリケーションおよびライブラリコードです。これは、他の人にアプリケーションやライブラリにインポートされたくないコードです。このレイアウトパターンは、Goコンパイラ自体によって強制されます。詳細については、Go 1.4のリリースノートを参照してください。なお、これはトップレベルのinternalディレクトリに限定されません。プロジェクトツリーの任意のレベルに複数のinternalディレクトリを持つことができます。

共有と非共有の内部パッケージを区別するために、内部パッケージに追加の構造を追加することを選択することができます。これは必須ではありません(特に小規模なプロジェクトに関しては)、が意図したパッケージの使用方法を視覚的に示すことは良い慣行です。実際のアプリケーションコードは、/internal/appディレクトリ(例:/internal/app/myapp)に配置し、これらのアプリケーションの共有コードは/internal/pkgディレクトリ(例:/internal/pkg/myprivlib)に配置できます。

/pkg

外部のアプリケーションが使用できるライブラリコードです(例:/pkg/mypubliclib)。他のプロジェクトはこれらのライブラリをインポートし、正常に動作することを期待しますので、コンテンツを配置する前に慎重に考えてください :-) internalディレクトリは、Go自体によって強制されているため、私用のパッケージをインポートできないようにするためのより良い方法です。/pkgディレクトリは、このディレクトリのコードが他の人が安全に使用できることを明示的に伝える良い方法です。

プロジェクトが非常に小さく、多階層のネストがあまり価値を追加しない場合は、それを使用しないことも構いません(本当に使用したい場合を除きます)。プロジェクトが十分に大きくなり、ルートディレクトリが非常に忙しくなった場合は、それを検討してください(特に多くのGo以外のアプリケーションコンポーネントがある場合)。

/vendor

アプリケーションの依存関係(手動で管理するか、組み込みのGo Modules機能などを使用している)に注意してください。go mod vendorコマンドを使用すると、/vendorディレクトリが作成されます。デフォルトで有効になっていないGo 1.14バージョンを使用している場合は、go buildコマンドに-mod=vendorフラグを追加する必要があります。

ライブラリをビルドしている場合は、アプリケーションの依存関係をコミットしないでください。

サービスアプリケーションディレクトリ

/api

OpenAPI/Swaggerの仕様、JSONスキーマファイル、プロトコル定義ファイル、およびAPIプロトコルディレクトリ。

Webアプリケーションディレクトリ

/web

Webアプリケーション向けの特定のコンポーネント:静的ウェブサイトのアセット、サーバーサイドのテンプレート、およびシングルページアプリケーション(SPA)。

一般的なアプリケーションディレクトリ

/configs

構成ファイルのテンプレートまたはデフォルトの構成。

ここにconfdまたはconsul-templateのテンプレートファイルを配置してください。

/init

システムの初期化(systemd、upstart、sysv)およびプロセスマネージャ/デーモン(runit、supervisord)の設定。

/scripts

様々なビルド、インストール、解析、その他の操作用スクリプト。

/build

パッケージングと継続的インテグレーション。

クラウド(AMI)、コンテナ(Docker)、オペレーティングシステム(deb、rpm、pkg)パッケージの構成とスクリプトを /build/package ディレクトリに配置してください。

継続的インテグレーション(travis、circle、drone)の構成とスクリプトを /build/ci ディレクトリに配置してください。特定の継続的インテグレーションツール(Travis CIなど)は、構成ファイルの配置場所に非常に厳格です。可能であれば、構成ファイルを /build/ci ディレクトリに配置し、それを継続的インテグレーションツールが期待する場所にリンクするようにしてください。

/deployments

IaaS、PaaS、システム、およびコンテナオーケストレーション(docker-compose、kubernetes/helm、terraform)の展開構成とテンプレート。一部のリポジトリ(特にKubernetesを使用して展開されるアプリケーションの場合)では、このディレクトリは/deployと呼ばれる場合があります。

/test

その他の外部テストアプリケーションとテストデータ。/testディレクトリを自分のニーズに合わせて整理してください。プロジェクトが大規模な場合は、データをサブディレクトリに整理することが理にかなっています。たとえば、/test/dataまたは/test/testdataディレクトリを作成して、Goがその内容を無視するようにすることができます。Goは"."や"_"で始まるディレクトリやファイルも無視しますので、テストデータディレクトリの命名においてより柔軟性を提供しています。

その他のディレクトリ

/docs

設計とユーザードキュメント(godocドキュメント以外)。

/tools

このプロジェクト向けのサポートツール。これらのツールは/pkgおよび/internalディレクトリからコードをインポートできることに注意してください。

/examples

アプリケーションや公共ライブラリの例。

/third_party

外部の補助ツール、フォークされたコード、およびその他のサードパーティ補助ツール(例:Swagger UI)。

/githooks

Gitフック。

/assets

リポジトリに含まれる追加のアセット(画像、ロゴなど)。

/website

GitHub Pagesを使用していない場合のプロジェクトウェブサイトデータの保存場所。

/src

一部のGoプロジェクトにはsrcフォルダがあるかもしれませんが、これは一般的にはJavaの世界から来た開発者が採用しているためです。可能であれば、このJava風のパターンは避けるようにしてください。GoのコードやプロジェクトがJavaのように見えることは避けたいです :-)

プロジェクトレベルの/srcディレクトリと、How to Write Go Codeで説明されているGoワークスペースで使用される/srcディレクトリとを混同しないでください。$GOPATH環境変数は(デフォルトでは非Windowsシステム上では$HOME/goディレクトリを指します)現在のワークスペースを指します。このワークスペースにはトップレベルの/pkg/bin/srcディレクトリが含まれます。実際のプロジェクトは/srcディレクトリのサブディレクトリになりますので、プロジェクトに/srcディレクトリがある場合、プロジェクトパスは次のようになります:/some/path/to/workspace/src/your_project/src/your_code.go。Go 1.11以降、プロジェクトをGOPATHの外に配置することができますが、このレイアウトパターンを採用することが良い考えであるとは限りません。