Go初心者がさっくりAPIサーバを立てる

Go初心者です。
昔Tour of Goを一通り触って、
あれ？Goでサーバってどうやってたてるんだっけ？
というところがわかってなかったのでその辺やってみようと思います。

Go言語の良さは次の点があげられると思います。

* 言語の仕様が最小限
* コンパイル型言語（文法エラーチェックができる）
* 並列処理

このため、最近の特にレイテンシを求められるようなビジネスロジックやプッシュサーバ等、
バックエンドサーバ用として主流の言語です。

NodeJSはイベントループの壁があるからGoのほうが
スケールするという記事をみかけたのも勉強しようと思ったきっかけです。
（NodeJSも、JSの知識使いまわせたり、npmのエコシステム大好きですけど）
[Gopherの道を歩む – Node.jsからGo言語への移行](http://postd.cc/the-way-of-the-gopher/)

# Goの導入
![fiveyears.jpg](https://qiita-image-store.s3.amazonaws.com/0/55077/3acc038b-ca9d-8ba2-d768-19b6eb947338.jpeg)
Go言語マスコットキャラの[Gopher](http://qiita.com/mattn/items/b7889e3c036b408ae8bd)君です

インストールガイドどおり
`/usr/local/go`に展開して、環境変数のパスを通します。
[Goのインストール](http://golang-jp.org/doc/install)

$GOPATHも設定します
下記参考によるとどこでも良いらしいですが、一度決めたら変更は難しいようです。
[GOPATH は適当に決めて問題ない](http://qiita.com/yuku_t/items/c7ab1b1519825cc2c06f)

ちなみに私は~./bash_profileに次のように設定してます（Mac環境）

```bash
export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$GOROOT/bin:$GOPATH/bin:$PATH
```

goではgo getと呼ばれるコマンドでgitのソースコードをダウンロードすることができます。
以下のフォルダに配置されます。
`$GOROOT/src`
詳細は下記を参考にしてください
[go getコマンド](http://cuto.unirita.co.jp/gostudy/post/command-go-get/)

# 開発環境
IDEとか使わなくても開発できますがIDEのほうが
コード補完してくれたりデバッグのブレークポイントかけられたりで楽なので導入したほうが良いでしょう。
Android Studio IDEとかを作っているJetBrainsが提供している
[Goland](https://www.jetbrains.com/go/)がIDEとしてイケてます。
まだEarly Build版ですが・・・

基本的な使い方は下記を参考にしてください
参考：[Gogland - Go 言語用 IDE - を使ってみた (2016年12月版)](http://qiita.com/pankona/items/380f8b08e39d469ca94d)

# Goの文法
Goの文法は次のチュートリアルを一通りやればマスターできます。
[Tour of Go](https://go-tour-jp.appspot.com/welcome/1)
Go2がそろそろ来そうですが・・・

# Goのライブラリ
標準ライブラリパッケージ
[Standard library](https://golang.org/pkg/)

よく使いそうな系のライブラリはここ見れば大抵あるようです。
[Awesome Go](https://github.com/avelino/awesome-go)

知っておくと良さそうなライブラリ
[楽ができるGolangのライブラリ達](http://qiita.com/shunsukeaihara/items/ba6472910db885f436a0)

# アプリケーションサーバを立てる
[Goa](https://github.com/goadesign/goa)というフレームワークが良いらしいです。
APIのビジネスロジックに集中できるのと[Swagger](http://editor.swagger.io/#/)というAPI仕様ファイルを生成してくれます。
SwaggerはAPI仕様とともにモックサーバ作れたり、ブラウザ上でAPIテストできたりとかなり便利なので知っておいて損はないです。（YAMLやjson形式なのでgitで変更管理もできるし）
参考：[SwaggerでAPIを定義してインタラクティブAPIドキュメントを見る](http://qiita.com/NewGyu/items/64adc3c5dd3ab8ad6087)

Goaのインストールは次リンクが参考になります。
参考：[goa のインストールと実行](http://ikawaha.hateblo.jp/entry/2016/09/12/164728)

Goaの作り方まとめてるページがあるので参考にさせてもらって進めます。
[GolangのgoaでAPIをデザインしよう（基本編）](http://tikasan.hatenablog.com/entry/2017/05/05/212501)

# ORM(DB操作)
goaではgormaと呼ばれるORMでDB操作します。
[GolangのgoaでAPIをデザインしよう（Model編）](http://tikasan.hatenablog.com/entry/2017/05/15/172535)

裏側では[gorm](https://github.com/jinzhu/gorm)というORMが使われているらしいです。
gormの使い方はここが詳しいです。
[【GORM】Go言語でORM触ってみた](http://qiita.com/chan-p/items/cf3e007b82cc7fce2d81)

# サンプルのAPIサーバを立てる

TODOリストサーバを立ててみます。
$GOPATH/srcフォルダ以下にtodolistフォルダを作ります。
goaではdesignフォルダ以下にAPI実装を書くため、designフォルダもついでに作ります。

```bash
mkdir -p $GOPATH/src/todolist/design
cd $GOPATH/src/todolist
```

goglandで$GOPATH/src/todolistフォルダを開きます。
<img width="283" alt="スクリーンショット 2017-07-22 20.28.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/55077/24f571e0-ab39-f86f-dd76-6e05f3bc6401.png">

design.goファイルを作成します。
<img width="643" alt="スクリーンショット 2017-07-22 20.28.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/55077/716b3550-34b8-058e-6a49-c94a569a0c86.png">
<img width="461" alt="スクリーンショット 2017-07-22 20.34.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/55077/0bb20860-b42e-ec99-be4e-2dd4c2369f55.png">

design.goは次のように記述します。

```design.go
package design                                    

// package "design"
import (
	. "github.com/goadesign/goa/design"        
	. "github.com/goadesign/goa/design/apidsl"
)

var _ = API("todolist", func() {                   
	Title("The virtual todolist")       
	Description("A simple goa service") 
	Scheme("http")                    
	Host("localhost:8080")
})

var _ = Resource("todolist", func() {            
	BasePath("/todolist")                      
	DefaultMedia(TodoListMedia)                  
	
	Action("show", func() {           
		Description("Get todo by id")    
		Routing(GET("/:todoID"))         
		Params(func() {                    
			Param("todoID", Integer, "Todo ID")
		})
		Response(OK)                      
		Response(NotFound)                
	})
})

// TodoListMedia defines the media type used to render todolist.
var TodoListMedia = MediaType("application/vnd.goa.example.todolist+json", func() {
	Description("A todo of todolist")
	Attributes(func() {                        
		Attribute("id", Integer, "Unique todo ID")
		Attribute("href", String, "API href for making requests on the todo")
		Attribute("name", String, "Name of todo")
		Required("id", "href", "name")
	})
	View("default", func() {               
		Attribute("id")                    
		Attribute("href")                  
		Attribute("name")
	})
})
```

goagenコマンドのbootstrapオプションでテンプレート生成します。

```bash
$goagen bootstrap -d todolist/design
```

プロジェクトのtodolistフォルダを右クリックしてRunします。
<img width="609" alt="スクリーンショット 2017-07-22 20.47.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/55077/b9415487-4626-b517-7503-d2cc377eb337.png">

`http://localhost:8080/todolist/(:todoID)`にアクセスします。
<img width="297" alt="スクリーンショット 2017-07-22 20.58.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/55077/ab7e000c-7b80-5385-113e-2849b8faca36.png">


# DSL
DSL(domain-specific language、DSL）とは特定のタスク特定のタスク向けに設計されたコンピュータ言語を指します。
goaではAPI定義、エンティティ（ORMモデル）定義、Swaggerドキュメント定義等をgoa専用DSLで定義することができます。
記述したdesign.goがそれに該当します。

# goagen
上記のDSLを解釈してコードを自動生成してくれるツールです。
開発者はDSLだけを書けば、後はgoagenで自動生成できます。


| サブコマンド | 説明 |
|---|---|
|bootstrap|	初回に実施するコマンド (main/app/client/swaggerを実行する)|
|main|	APIサーバの main とコントローラーを作業ディレクトリに生成．このコマンドで生成されるファイルは上書きされない (--forceオプションで上書きを強制可能)|
|app	|アプリケーションのテンプレートを app ディレクトリ以下に生成|
|client	|APIサーバに対応するクライアントのコードを client / tool ディレクトリ以下に生成|
|swagger	|APIサーバの使用を swagger 形式で swagger ディレクトリ以下に出力|
|js	|JavaScript のAPIサーバクライアントを js ディレクトリ以下に生成|
|schema	|API の JSON スキーマを schema ディレクトリに生成|
|gen	|サードパーティの generator を利用するときに指定する．gorma とか使いたいときに利用|