Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
353
Help us understand the problem. What is going on with this article?
@yagi_eng

Goプロジェクトのはじめかたとおすすめライブラリ8.5選。ひな形にも使えるサンプルもあるよ。

はじめに

最近イケイケな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/...
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

サンプル

あくまでも簡易的なものです。。
こちら(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)直下に作成されます。

go.mod
module github.com/(GitHubユーザ名)/(GitHubリポジトリ名)

go 1.15

ライブラリをインストールすると、そのファイル内にパッケージの依存情報が記載されます。
かんたん便利!

モジュール名

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 で Lambda 書いたときの覚え書き

プロジェクトの配置場所

簡単に説明

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
go.mod
module github.com/yagi-eng/hoge-pj

go 1.15
hoge.go
package hoge // 自作パッケージ

import "fmt"

func PrintHoge() {
    fmt.Println("hogehoge")
}

main.go
package main

import "github.com/yagi-eng/hoge-pj/hoge" // こんな感じでimport!

func main() {
    hoge.PrintHoge()
}

こんな感じでimportすれば実行できます。

$ go run main.go
hogehoge

おすすめパッケージ

インストールしておくと捗りそうなパッケージを紹介します。

パッケージのインストール方法

以下のコマンドを実行するだけです。Go Modulesがいい感じにインストールしてくれます。

$ go get -u (インストールしたいパッケージ名)

# 例 echoフレームワークをインストールする場合
$ go get -u github.com/labstack/echo/...

echo

Goの軽量フレームワーク。
簡単にルーティングやサーバ実行、ロギング、CORS設定などをすることができます。

公式HPはこちら

$ go get -u github.com/labstack/echo/...

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より高速なようです。
こっちを使った方が良さそうですね。

$ go get -u go.uber.org/zap

fasthttp

net/httpとfasthttpの対応表

go言語でHTTP通信を行うためのライブラリです.

go言語の標準パッケージではnet/httpがすでに用意されているのですが,
fasthttpでは標準パッケージを凌駕する処理の速さで一時期有名になりました.
公式のベンチマークでは,従来に比べ10倍の差がでたようです.

$ go get -u github.com/valyala/fasthttp

gomock

mock生成ライブラリ。
簡単にモックを作成できるので、テストを実装する時などに便利です。

Goでメソッドを簡単にモック化する【gomock】

$ go get -u github.com/golang/mock/gomock
$ go install github.com/golang/mock/mockgen

wire

DIライブラリ。いい感じにDIできます。

GoのDIライブラリgoogle/wireの使い方

$ 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 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ライブラリ。
記事を読んで頂いた方に紹介頂きました!
自分はrealizereflexも使えなかったので結局こちらを使っています。

cosmtrek/air

$ 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を参照ください。
wiregomockなどはインポートはしましたが、サンプルでは使っていません。
記念に入れておいただけなので、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の方でも、モダンな技術習得やサービス開発の様子を発信したりしているので良かったらチェックしてみてください!

また、BOT開発を通じてGoとLINE BOTにまとめて入門する記事をZennに掲載していますので、良かったらそちらもご覧ください!

参考記事

353
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
yagi_eng
フリーのWeb系エンジニアです。マネジメントやディレクション的なところもやっています。元はクラウドエンジニアでした■モダンな技術習得やサービス開発の様子をTwitterで発信しているので良かったら覗いてみてください!■仕事依頼はTwitterにDM頂けると幸いです■ちなみに趣味は海外旅行やグルメ巡りです

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
353
Help us understand the problem. What is going on with this article?