個人開発でGo+Gin+GormでAPIサーバを作ろうとした際に、コードを独自パッケージに切り出した。
パッケージの扱いが多言語とちょっと違って戸惑ったのでメモ。
やろうとしたこと
最初main.goに書いていたGormでのMySQLへの接続処理をdbパッケージに、Ginで書いたAPIサーバをserverパッケージに切り出した。
それをmain.goにimportしようとしたら思いの外苦戦してしまった。
import先のパス指定方法
独自パッケージのimport方法はやり方がいくつかあり
- 相対パス(import ../db)でimportするか
- 独自パッケージのパスにgo.modを置いて「import "local.packages"」と指定してimportする
- github.com/{アカウント名}/{リポジトリ名}を指定してimportする
jsとかの感覚だと相対パスでやってしまいたくなるけど、github.com/{アカウント名}/{リポジトリ名}を指定したimportの仕方が推奨っぽいのでそのやり方で進めた。
あと独自パッケージのパスにgo.modを置くやり方でもimportできたけどこっちも非推奨らしい
ローカルパッケージとしてのimportはまず以下のようにgo.modを作って
module movie-info/ikeyu0806/db go 1.14 replace local.packages/db => ./db
で、main.goで独自パッケージをimportする
import "local.packages/db"
これでも動いたけど、最終的にはgithubのパス指定してimportする形にした。
package main import ( "github.com/ikeyu0806/movie-info-backend/db" "github.com/ikeyu0806/movie-info-backend/server" ) func main() { db.Init() server.Init() }
GOPATHのこと
このやり方(github.com/{アカウント名}/{リポジトリ名}の形式)でimportするには - githubに同じパスでpushする or - GOROOT以下のパスを合わせる
のどっちかが必要で、pushせずに作業するには GOROOT/github.com/{アカウント名} の直下にプロジェクトをおかないといけない。
最初GOROOTに合わせる形で進めたけど作業パスここまで深くするのはなんか違和感があった。 dockerの中で開発全てやってしまうのであれば問題ないんだろうけど。
あとgoをinstallした時にできる環境変数としてGOROOTというものがあってややこしいけど、こっちは変更してはいけない(うっかり変更したらgo buildがエラーになった)
感想
他の言語の感覚だと相対パス指定でimportしたくなるし独自パッケージ作るたびにいちいちgithubにpushしたり作業パスをgithubに合わせたりするの大分違和感あるけどこの辺の感覚は慣れなのかな?
Gemとかnpmみたいにライブラリを配布するサーバがないところもGo特有っぽい。