LoginSignup
0
0

【Go】go.mod を複数使いたいときは、go.workを作って解決しよう!

Last updated at Posted at 2023-12-18

どういった背景があったのか

 マイクロサービス化を導入してる都合上、gRPCを使って通信をしていました。主にprotoファイルといった通信規格を定義するファイル群を疎通を行う双方向のサーバーに配置するのが一般的だと思います。
 よくあるケースとして、protoファイル群を1つのリポジトリにまとめ、そのリポジトリをシステム間で参照するといったケースを見かけると思います。

・マイクロサービス化したシステム構成になっている
・各システム間で、特定のリポジトリのスキーマを参照したかった
・GitSubModulesなどを導入して、これらを実現したかった

どういった状況だったのか

 この場合、特定のリポジトリに対し、protoファイル群をまとめたものを置くことになるため、以下のような構成になるのではないでしょうか。

service_1
├── microservice_scheme // protoファイル群が入ったリポジトリ
│   ├── go.mod // go.modが複数ある状況が生まれる
│   ├── go.sum // go.sumが複数ある状況が生まれる
│   └── main.go
├── go.mod
├── go.sum
└── main.go

 GitSubModulesなどを使って、こういったディレクトリ構成にするなどの手順が一般的だと思います。

 このようなときに、go.modが複数ある状況が生まれてしまうんですよね。。

 こうなると、go mod 系のコマンドや gopls も正しく動作・解釈してくれません。vscodeがエラーの嵐になります。。

どうやって解決したのか

 単一のリポジトリ内に複数の go.mod を配置したとき、上述した障壁が出てきたと思います。
 実は、この解決方法は、意外と簡単です。

プロジェクトのルートディレクトリに go.work というファイルを配置し、

単一のリポジトリだけど、複数の go.mod が存在するよっ

と伝えてあげれば解決ができます。

なので、さっきのケースを元に go.work を追加すると以下のような構成になります。

service_1
├── microservice_scheme // protoファイル群が入ったリポジトリ
│   ├── go.mod // go.modが複数ある状況が生まれる
│   ├── go.sum // go.sumが複数ある状況が生まれる
│   └── main.go
├── go.mod
├── go.sum
├── go.work // ルートディレクトリに置く
└── main.go

あとは、 go.work 複数の go.mod が存在するよっと伝えてあげればいいので、

go 1.21

use (
    ./microservice_schema
)

 このような書き方をすると、うまく動作・解釈してくれると思います!

まとめると

 go.work というファイルを特定の配置場所に置いてあげることで、うまく gopls などが反応し、解決ができました。
 goでは、もっと厳密にいうと go.mod では、インストールしたpkgをモジュールという単位で管理をしています。

このファイルを置くことによって、
単一のプロジェクト内に複数のモジュールが、枝分かれされていると解釈され、

service_1 で扱ってるモジュールと microservice_scheme で扱ってるモジュールは、それぞれ異なるもの

とこちらが期待していた解釈になる訳です。

余談

 こうした知見は、時間があるときに go.dev なんかを読み漁ると、知見が深まりそうだなーと感じました。
 皆さんもぜひお時間あるときに一読してみてはいかがでしょうか!

・multi-module に関して体系的に、ハンズオンで書かれていて、面白かった

・go.workを使ったときの、複数のモジュールがどう切り分けされるか、イメージ図が添付されていて、理解が進んだ

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