なかなか入門できなかった人のためのgo+ginによるAPI開発入門以前

なかなか入門できなかった自分のために、Goの入門以前レベルの記事が欲しいなと思いました。

流行に敏感なGopher[^1]の諸賢から見るとめちゃくちゃ言っている可能性もありますが、自分なりにこれならわかりやすいんじゃないかな〜という目線でまとめてみています。

なお、記事執筆時点でGoのstableバージョンは1.12.1ですのでその想定で進めます。

# 想定読者

- Goを始めようとしたけどずっと分からなくて何度も挫折している
- 出来るだけシンプルな構成でGoを始めたい
- GoでAPIを作りたいけどよく分からない
- Ginって噂は聞くけどまだよく分からない
- GoでAPIが動けばいい。逆にいうとあんまり高度なことを最初から書かないでほしい

# あまり想定していない読者

- 非Macな方
- Goの文法が知りたい
    - [A Tour of Go](https://go-tour-jp.appspot.com/welcome/1) ならリアルタイムで動かせてとてもわかりやすいです。
- Goのアーキテクチャとかを学びたい
    - 知見不足で良い記事がまだ分からないので参考資料割愛。クリーンアーキテクチャとかで記事が大変多くあるようです
    - https://github.com/golang-standards/project-layout 噂によるとこの辺が参考になるらしい
- Ginに入門したい
    - https://qiita.com/Anharu/items/ce644c521a4d52fafb7e この方の記事とかわかりやすそう
- Goのお作法を学びたい
    - 噂によるとこれがデファクトスタンダードのようです。
    - [CodeReviewComments](https://github.com/golang/go/wiki/CodeReviewComments)
    - 和訳： [#golang CodeReviewComments 日本語翻訳](https://qiita.com/knsh14/items/8b73b31822c109d4c497)
    - [Effective Go](https://golang.org/doc/effective_go.html) とかいう経典みたいなものがあるとのこと
- Goのよく使われるモジュールとか知りたい
    - 勉強中なので待ってほしい

# disclaimer

書いた人は基本はRubyist、ちょっとSwiftも書く、みたいな人です。
そんな目線で書かれているところが随所にあります。
環境構築とかサンプルコードの段階で複雑すぎると凹んじゃうタイプなので、自分でも心が折れないような粒度にしようと思いました。

# Goの特徴について

まだよく分からないんですけど、以下のような特徴があるらしいです。

- 静的型付け言語
    - 型が強制されるっていいですよね。僕は好きです。メリットとしては、コンパイル時点で不適切な処理を見つけ出しやすくなるというのがあります。静的解析や自動テスト、Linterなどと相性がいいという噂です。
- コンパイル型言語
    - インタプリタ的に動かすこともできます(内部的にどっちなのかはまだ調べてないです)が、コンパイルしてシングルバイナリ実行ファイルに落とし込むことができます。
    - 依存しているライブラリなどがほとんどなく、様々な実行環境で安心して動かせるということでポータビリティが高い、なんて言われたりしているようです。
- シンプルな言語仕様
    - Goはあまり多くの言語仕様をサポートしていないらしいです。黒魔術みたいなことよりも、多少冗長でも(ここは誤解があるかも)シンプルで素直な記述をすることを好むとのこと。
- 並列処理を言語レベルでサポート
    - differとかContextとかそんな単語を噂に聞きます(まだよくわかってない)

# Goをインストールする

この記事ではHomebrewを使います。
Homebrewが入っていない人は・・・ [Homebrew 公式サイト](https://brew.sh/index_ja)からいい感じによろしくお願いします。
入っているか自信がないあなたは、terminalでおもむろに `brew --version` と打ちましょう。バージョン情報が返ってくれば多分大丈夫です。

さて、以下のコマンドをterminal上で実行することでGoをインストールできます。
その時点での最新の安定版がインストールできるはず。

`brew install go --HEAD`

https://formulae.brew.sh/formula/go

`go version`

を実行して、

`go version go1.12.1 darwin/amd64`

のような結果を受け取れれば成功です。

## バージョン管理がしたい人はgvmがいいらしい

こちらの記事などが参考になるかも。
僕は噂に聞く Go Modules が動いてくれればなんでも良かったので今回はスルーしています。
https://qiita.com/keiichi-hikita/items/5a798b35867c057d16d1

Goはdockerとかと組み合わせて使うことが多くてローカル環境でバージョン管理する必要性をあまり感じない、なんて話も時たま聞きます。

# Goを動かす

Goのコードを書きましょう。
最初に呼び出されるファイルはmain.goという名前をつけることが多いようです。

```main.go
package main

import "fmt"

func main() {
	fmt.Println("Hello, 世界")
}
```

A Tour of Go からそのまま拝借しています。

動かすときは、

`go run main.go`

を実行します。

`"Hello, 世界"`

という風にterminalの標準出力に出てくれば成功です。

# Goをコンパイルする

Goの特徴について、のところで言及した通り、シングルバイナリの実行ファイルにすることができます。すごい便利そう。

やり方ですが、非常に簡単です。

`go build main.go`

とすると、同じディレクトリに

`main`

というファイルが生成されます。これで完了です。

# コンパイルしたファイルを動かす

この生成されたファイルを実行するときは、

`./main`

とすることで実行可能です。実行ファイルなので、ファイルを呼び出すだけで動くんですね。

ちなみに、単純に `main` とやると実行ファイルの呼び出しではなくbashのコマンド呼び出しと解釈されるみたいで、僕の環境では `-bash: main: command not found` となってしまってうまく動きませんでした。

# ginを導入する

さて、ginを導入していきたいわけですが、ginは外部のパッケージなので使える状態にする必要があります。
そのために、 `Go Modules` というGoの公式のパッケージ管理機能を使っていきましょう。

## Go Modulesを準備する

では、つい最近Go標準パッケージ管理ツールとなったGo Modulesを使ってやっていきます。

Go Modulesを使うためにいくつか準備を進めましょう。
まず、Go Modulesを使うためには、

`GO111MODULE=on`

という指定が環境変数に追加されている必要があります。
環境変数以外のやり方もあるのかもしれませんが、とりあえずこれは動きます。動きました。

`~/.bash_profile` または `~/.bashrc` の末尾あたりに、

``` ~/.bash_profileまたは~/.bashrc
export GOPATH=$HOME/go
export GO111MODULE=on
```

この二つの記述を追記しましょう。いいですか、追記ですからね。 [^2]

ここまでできたら、追記した方のファイル(今回は `~/.bash_profile` とします)を読み込みます。
以下のコマンドをterminalで実行しましょう。

`source ~/.bash_profile`

うまくいってるかは、

`printenv | grep GOPATH`
`printenv | grep GO111MODULE`

とかで確認できます。

環境変数の設定ができたら、パッケージ依存関係管理をするための初期化を行います。

`mkdir -p ~/go/src/github.com/gotest`
(※ `gotest` の部分は任意の名前です。 path も src 配下なら必須とかではないかも)

みたいな感じでディレクトリを作って、

`cd ~/go/src/github.com/gotest` [^3]

して今回の開発用ディレクトリに移動しましょう。今回はここを実験場とします。

このディレクトリで、

`go mod init`

を実行します。

`ls` したときに、 `go.mod` というファイルが作られていれば準備完了です。

## ginをインストールして動かす

いよいよ gin を使う main.go を書いていきましょう。こんな感じ。動けばok。
githubの公式リポジトリ、 [gin-gonic/gin](https://github.com/gin-gonic/gin) のサンプルそのままです。

```main.go
package main

import "github.com/gin-gonic/gin"

func main() {
  r := gin.Default()
  r.GET("/ping", func(c *gin.Context) {
    c.JSON(200, gin.H{
      "message": "pong",
    })
  })
  r.Run() // listen and serve on 0.0.0.0:8080
}
```

このファイルができたら、同じく `~/go/src/github.com/gotest` ディレクトリで、

`go run main.go`

をしましょう。
Go Modulesが依存関係を解決して、必要なパッケージをインストールしてくれるので、しばらく待てばプロセスが立ち上がります。プロセスが立ち上がったら、 `localhost:8080/ping` にアクセスしましょう。

```
{
  "message": "pong"
}
```

というAPIレスポンスが取得できるはずです。

個人的にすごいなーと思うのは、

```.go
import "github.com/gin-gonic/gin"
```

と書いただけでgithubから依存関係を解決してくれちゃうところですね。github上のリポジトリを使いたいときにものすごく素直に使える感じがしてとても好きです。

`go build main.go`

すれば、依存パッケージも含めてビルドしてくれるので、先ほど同様

`./main`

で localhost:8080 が立ち上がります。

それでは、良い go/gin のAPI開発ライフをお送りください。

### オマケ: ところで `export GOPATH=$HOME/go` ってなに？

環境変数 `$GOPATH` というのを指定する記述です。依存関係を管理したりいろんなところで使うようです。

今回だと、 `$HOME/go` つまり `~/go` にしましたが、 `$HOME/.go` とかにする人もいるみたいです。

この `$GOPATH` にしたがって、 `$GOPATH/pkg/` ディレクトリ配下に依存関係にあるパッケージがダウンロードされます。

# そのうちやりたい

gormの使い方とか、dockerでどうやって動かすかとか、k8sにどうやってあげるかとか、そっち方面の勉強中なのでいつかまとめられたらいいなあ。と思いつつ終わりです。

みんなも幸せなGopherライフを送りましょう！

[^1]: GopherくんというGoの愛されマスコットになぞらえて、Goを書く人もGopherと呼ぶらしい
[^2]: 僕はここで `.bash_profile` 触るのもbashでファイルいじるのも久しぶりなのに雑にやろうとして ```echo `export GOPATH=$HOME/go` > ~/.bash_profile``` とかやって設定吹き飛ばしました。一瞬マジでヤバいかと思った。(普段使う機能は復旧できました)。なんか別のところで似たような記述を見て「えーこれ追記してくれるんだ〜」と思ってめっちゃ雑にやったんですけど末尾追記は `>>` であって `>` ではダメです。 `>` でやると上書きで吹き飛びます。つまり ```echo `export GOPATH=$HOME/go` >> ~/.bash_profile``` が正しかった。。
[^3]: $GOPATH/src/github.com/USERNAME/REPONAME という形式でディレクトリを掘るのが慣習的に好まれているようなので、特にこだわりがない方はそれに倣うと良さそうです。