はじめに
最近イケイケなGo!
でもベターなGoプロジェクトのはじめかたっていまいち調べてもわからないですよね。
自分は最初色々迷いました。。
まずパッケージ管理ツール。
godepだったりGo Modulesだったり、少し情報がとっちらかっている印象です。
後はどのディレクトリにプロジェクトを配置した方がいいのかもわかりづらい。
importの仕方も相対と絶対のどちらがいいのか迷う。
というわけで以下の4点に絞って解説していきたいと思います!
- パッケージ管理ツール
- プロジェクトの配置場所
- 自作パッケージのimportの仕方
- おすすめライブラリ
この記事を読めば正しくGoプロジェクトが作成できます!(たぶん)
【追記】
インストール方法とVSCodeの設定に関しても簡潔にまとめたので、良かったら参考にしてください。
【超簡単】GoのインストールとVSCode設定方法
いきなりまとめ
プロジェクト作成
新規にGoプロジェクトを作成したい場合は以下の通りにコマンドを実行すればOKです。
$ cd (任意のディレクトリ)
$ mkdir (YOUR_PROJECT)
$ cd (YOUR_PROJECT)
$ go mod init github.com/(GitHubユーザ名)/(GitHubリポジトリ名)
# 後はどんどこファイル作成!
$ vim main.go
# あるいは必要なパッケージをインストール
$ go get ~~~~~
...
おすすめライブラリインストール
go mod init
後に必要に応じて実行。
あるいは各ソースコードのimport文にライブラリのパスを記載しておくと、go run
の時に自動でインストールしてくれます。
go get -u github.com/labstack/echo/v4
go get -u github.com/joho/godotenv
go get -u github.com/sirupsen/logrus
go get -u github.com/valyala/fasthttp
go get -u github.com/golang/mock/gomock
go install github.com/golang/mock/mockgen
go get -u github.com/google/wire/cmd/wire
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql # mysqlを使う場合
go get -u github.com/oxequa/realize
【2021/4/21追記】
Go1.16よりgo install
を使ったインストールもできるようになっています。
直近では上記インストール方法で問題ありませんが、詳細は各ライブラリのREADMEをご確認ください。
また、go install
については、以下の記事がわかりやすかったです。
Go1.16からの go get と go install について
サンプル
あくまでも簡易的なものです。。
こちら(GitHub)です。
パッケージ管理ツール
簡単に説明
現在はGo Modulesが標準なのでこちらの機能を使いましょう。
Go Modulesが標準で使えるようになる前は、godepなどが使われていたらしいです。
Go言語の依存モジュール管理ツール Modules の使い方
Modules は、依存モジュール管理ツールです。
Go言語 1.11 から標準で使えるようになりました。
以下のような機能を持っています。
・依存モジュールの自動検知
・依存モジュールのバージョン固定、バージョンアップ検知
・依存モジュールの情報は go.mod と go.sum という名前のファイルに記載されます。
使い方
新規にディレクトリを作成し、go mod init
と打つだけで、Go Modulesを使えるようになります。
$ mkdir (YOUR_PROJECT)
$ cd (YOUR_PROJECT)
$ go mod init github.com/(GitHubユーザ名)/(GitHubリポジトリ名)
go: creating new go.mod: module
そうすると、go.mod
ファイルが(YOUR_PROJECT)
直下に作成されます。
module github.com/(GitHubユーザ名)/(GitHubリポジトリ名)
go 1.17
ライブラリをインストールすると、そのファイル内にパッケージの依存情報が記載されます。
かんたん便利!
モジュール名
go mod init
でモジュール名(プロジェクト名)を指定する時は、慣習的にgitリポジトリのドメインから記載するようです。
色々漁ってみたんですけどソースはいまいちわかりませんでした。。
ただ、The Go Blog - Using Go Modulesでもそのように紹介されていました。
例えば私だと以下の通りです。
$ go mod init github.com/yagi-eng/go-pj-template
リポジトリURLはこちら。
https://github.com/yagi-eng/go-pj-template
GitHub以外、例えばCodeCommitだとこうなるらしい。
$ go mod init git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/hello.git
プロジェクトの配置場所
簡単に説明
Go Modulesの登場により、どこでも配置できるようになりました。
以上です。
以前は
Go Modulesの登場以前は$GOPATH/src
(※)配下に配置する必要がありました。
他言語からくると、置く場所が決まっている点に少し戸惑いますが、解消されたようです。
※$GOPATH
はデフォルトだと$HOME/go
どこでも配置できるようになったけど、なんかGoっぽいので自分は以下の例の通りに配置しています。
具体例
$GOPATH
├─ bin/
├─ pkg/
└─ src/
└─ github.com/
└─ GitHubユーザ名/
└─ GitHubリポジトリ名/
├─ main.go
└─ などなど。気の向くままに配置。
自分の場合はこんな感じです。
$GOPATH
├─ bin/
├─ pkg/
└─ src/
└─ github.com/
└─ yagi-eng/
└─ go-pj-template/
├─ main.go
└─ などなど。気の向くままに配置。
$GOPATH/src/github.com/yagi-eng/go-pj-templete
自作パッケージのimportの仕方
簡単に説明
import "(モジュール名)/(自作パッケージ名)"
相対パスではなく、モジュール名から始まる絶対パスで指定します。
具体例は次の通りです。
具体例
モジュール名: github.com/yagi-eng/hoge-pj
自作パッケージ名: hoge
hoge-pj/
├─ hoge/ #自作パッケージ
| └─ hoge.go
├─ main.go
└─ go.mod
module github.com/yagi-eng/hoge-pj
go 1.17
package hoge // 自作パッケージ
import "fmt"
func PrintHoge() {
fmt.Println("hogehoge")
}
package main
import "github.com/yagi-eng/hoge-pj/hoge" // こんな感じでimport!
func main() {
hoge.PrintHoge()
}
こんな感じでimportすれば実行できます。
$ go run main.go
hogehoge
linter
staticcheckというlinterがおすすめです。
詳細はこちら。
おすすめパッケージ
インストールしておくと捗りそうなパッケージを紹介します。
パッケージのインストール方法
以下のコマンドを実行するだけです。Go Modulesがいい感じにインストールしてくれます。
$ go get -u (インストールしたいパッケージ名)
# 例 echoフレームワークをインストールする場合
$ go get -u github.com/labstack/echo/...
echo
Goの軽量フレームワーク。
簡単にルーティングやサーバ実行、ロギング、CORS設定などをすることができます。
公式HPはこちら。
$ go get -u github.com/labstack/echo/v4
godotenv
.env
ファイルを使用するためのライブラリ。
使い方は以下の記事が参考になります。
【Go】.envファイルをGolangでも使用するためのライブラリ「godotenv」
$ go get -u github.com/joho/godotenv
logrus
logの外部パッケージ。
Go標準パッケージのlog
はシンプル過ぎるので、ログレベルなど使いたい時に便利です。
【Go×ログ】logrusの使い方を簡単に分かりやすくまとめてみた
$ go get -u github.com/sirupsen/logrus
【追記】zap
こちらもlogの外部パッケージ。
記事を読んで頂いた方に紹介頂きました!
logrus
より高速なようです。
こっちを使った方が良さそうですね。
-
uber-go/zap
- README.mdにパフォーマンスに関して言及されています。
- golangの高速な構造化ログライブラリ「zap」の使い方
$ go get -u go.uber.org/zap
fasthttp
go言語でHTTP通信を行うためのライブラリです.
go言語の標準パッケージではnet/httpがすでに用意されているのですが,
fasthttpでは標準パッケージを凌駕する処理の速さで一時期有名になりました.
公式のベンチマークでは,従来に比べ10倍の差がでたようです.
$ go get -u github.com/valyala/fasthttp
gomock
mock生成ライブラリ。
簡単にモックを作成できるので、テストを実装する時などに便利です。
$ go get -u github.com/golang/mock/gomock
$ go install github.com/golang/mock/mockgen
wire
DIライブラリ。いい感じにDIできます。
$ go get -u github.com/google/wire/cmd/wire
gorm
GoのORマッパー。
2020年8月にVersion2.0がリリースされて、使い勝手が向上したみたいです。
$ go get -u gorm.io/gorm
$ go get -u gorm.io/driver/mysql # mysqlを使う場合
realize
hot reloadライブラリ。
Goはコンパイル言語なので、PHPのように変更が即反映されず、変更のたびにプロセスをキルしてgo run
し直す必要があります。
その点を解消してくれます。
ただし、Go Modulesを使っている場合はそのままだと動作しません。
ワークアラウンドをあてる必要があります。
- [Go] Realizeが便利なので、もう少し仲良くなってみる
-
Cannot do
--run
with go1.11 using go mod under windows.- ワークアラウンドはこちら。
$ go get -u github.com/oxequa/realize
補足
realizeはファイルが更新された際に、今動いているアプリを停止しないまま更新後のアプリを起動させようとします。
そのため、ポート番号を指定してGoサーバを起動していると、以下のようなエラーが出てうまくhot reloadされません。
{"time":"2020-09-04T15:29:06.6074496+09:00",
"level":"FATAL","prefix":"echo","file":"server.go","line":"41",
"message":"listen tcp :8080: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted."}
こちらもワークアラウンドが出てます。
Realize is not killing the current app
reflex
こちらもhot reloadライブラリ。
2つ目のhotreloadライブラリなので0.5扱いです。
realizeがダメだったら試してみるといいかも。
ただし、Windowsには対応していません。
goのhot reloadingにはreflexが便利だった
$ go get -u github.com/cespare/reflex
【追記】air
こちらもhot reloadライブラリ。
記事を読んで頂いた方に紹介頂きました!
自分はrealize
もreflex
も使えなかったので結局こちらを使っています。
$ go get -u github.com/cosmtrek/air
サンプル
こちら(GitHub)です。
はじめかた
# MySQL準備
$ docker-compose up -d
# migration実行
$ go run tools/migrate.go
# アプリ実行
$ go run server.go
説明
Goをいい感じに始められるサンプル・ひな形です。
Goがインストールしてあることを前提としています。
簡単なAPIサーバを立てる時や、Goを始めたばかりでどうプロジェクトを作成していけばいいかわからない時に有効だと思います。
本格的なGoプロジェクトを作る時には不向きです。
コードを読むとおわかり頂けるのですが、db *gorm.DB
を引きずりまわしているのでその点が辛みです。
本格的なプロジェクトを作成する際は、wire
などのDIライブラリを使うと捗ると思います。
go.mod
に記載されているライブラリに関しては、以下のQiitaを参照ください。
wire
やgomock
などはインポートはしましたが、サンプルでは使っていません。
記念に入れておいただけなので、go mod tidy
すると消えます。
サンプルに含まれる内容
-
gorm
を使ったMySQL接続 -
gorm
を使ったDB migrationのサンプル -
gorm
を使ったDB Read/Writeのサンプル -
echo
を使ったルーティング、ロギング、CORS設定 -
godotenv
を使った.env
ファイルの読み込み
本格的なGoプロジェクトに興味のある方は。。
手前みそですが、こちらの記事が参考になるかと思います。
Goとクリーンアーキテクチャで飲食店検索ができるLINE BOT作ってみた
以下のように、結構ゴリゴリつくりました笑
|--.env
|--docker-compose.yml
|--go.mod // Goのバージョン管理
|--Procfile // Herokuデプロイ
|--server.go // main関数
|--wire.go // DI用
|--domain
| |--model
| |--repository // databaseのinterface
|--infrastructure
| |--database
| |--mysql.go
| |--router.go // Routing
|--interfaces
| |--controllers
| |--gateway // 外部API通信
| |--presenter // LINE BOT出力
|--mock // 各層のmock
| |--gateway
| |--presenter
| |--repository
|--tools // DBマイグレーション
|--usecases
| |--dto // usecase用のDTO
| | |--favoritedto
| | |--googlemapdto
| | |--searchdto
| |--igateway // interfaces/gatewayのinterface
| |--interactor
| | |--usecase // usecases/interactorのinterface
| |--ipresenter // interfaces/presenterのinterface
さいごに
Twitterの方でも、モダンな技術習得やサービス開発の様子を発信したりしているので良かったらチェックしてみてください!
Goのプロジェクトのはじめ方や、おすすめのライブラリをQiitaにまとめました😊
— やぎぬ😇行動力エンジニア (@yagi_eng) September 6, 2020
Goのこの辺りの情報ってあまりまとまっていないので、Goに興味のある方やGo初心者の方には参考になると思います😌
特にパッケージ管理やディレクトリ配置などは最初は「ん?」ってなりがち😇https://t.co/gLNPlPLzbU
また、BOT開発を通じてGoとLINE BOTにまとめて入門する記事をZennに掲載していますので、良かったらそちらもご覧ください!
ZennでGoとLINE BOTの記事を書いてみました
— やぎぬ😇行動力エンジニア (@yagi_eng) November 7, 2020
⬇️BOT開発を通じてGoとLINE BOTにまとめて入門するhttps://t.co/QqsEESJMKa
5ステップに分け、「Hello Worldから始めて、飲食店検索ができるLINE BOTの実装まで」を解説しています
GoやLINE BOTに興味のある人は是非読んでみてください😇
24,000字超え😇