ORMを使ってRESTful API をつくる with GO, GORM and Gorilla mux~準備編（ORMはまだ！！）

#GoでRESTful API をつくる
前回の記事ではGoの練習としてChat Applicationをつくってみました。

今回はRESTful APIをつくってみます。
内容はシンプルなTo Doリストを作ろうかなと思います。
面白みはないけど、他に思いつかない...。

今回の僕の中でのポイントは**ORM**です。
これを通して理解を深めながら、Implementの練習になればいいなと思ってます。

##まずRESTful APIとは
RESTful APIとはREpresentational State Transferの略でソフトウェア同士が互いにやりとりするためにAPIの一種。
RESTful APIではURIでリソースを判別しGET、POSTなどのhttpメソッドによってリソースを操作する。

難しい概念で僕の解釈などに間違いがある可能性もあるの注意。

##ORMとは
Object-relational mappingの略。
簡単に言うと、オブジェクト指向言語でデータをいじろうと言うことです。多分。
リレーショナルデータベースにアクセスすることなく手慣れた言語でSQLを意識せずデータを操作することができます。

ORMにも色々と種類があります。
今回はGoのORMであるGORMを使います。

※追記（友人からのアップデート）:　MongoDBのようなドキュメントデータベースには必要であればODM(ObjectDocumentMapping/ObjectDataModeling)という技術を使うらしい。例（Mandango）

##今回使用するものたち
 - Go
 - Gorm
 - Gorilla mux
 - MySQL

##Gorilla mux
webツールキットであるGorilla muxを使ってルーティング制御を行います。

通例どうり4つのエンドポイントを用意します。
Create, Read, Update, Delete
Crudと呼ばれるものですね。
HTTPメソッドと

Create - POST
Read - GET
Update - PUT
Delete - DELETE

このように関連付けます。

##実際につくっていく
`GOAPI`なるフォルダに`main.go`と`todos.go`を作りました。

忘れないうちに
ゴリラをインストールしておきます。

`$ go get github.com/gorilla/mux`

[ゴリラのサイト](http://www.gorillatoolkit.org/pkg/mux)

###Paths
`/`　今回はpathの動作確認にでも使っておきます
`/todos` GET　ToDoリストを羅列します
`/todo/id` POST　新しくタスクを追加します
`/todo/id` PUT　すでにあるタスクを操作、編集します
`/todo/id` DELETE　タスクを削除します

 - `/`

まず動作確認もかねてただのテキストを返す`/`を作ります

```main.go
package main

import (
	"log"
	"fmt"
	"net/http"
	"github.com/gorilla/mux"
)

func Hello(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello! I'm ok")
}

func main() {
	r := mux.NewRouter()
	r.HandleFunc("/", Hello).Methods("GET")
	log.Fatal(http.ListenAndServe(":8081", r))
}
```

`import "github.com/gorilla/mux"`を忘れずに！

####func Hello
まずは`/`のリクエスト対応しテキストを返すファンクションを定義しておきます。
後に詳しく説明しますが、内容はただ
`"Hello! I'm ok"`
を返します（Writerがリスポンスとして書いてくれる？）。

####func main
muxを使って新しいラウターを定義します。

`HandleFunc`で`uri`とそれに対応するレスポンスを紐づけます。
今回はに先ほど定義した`func Hello`を`/`に対応させています。

また`Method("GET")`によりHttpメソッドを指定することができます。

`http.ListenAndServe(":8081", r)`
によってポート8081でサーバを起動します。
rにはラウターが対応します。
muxなどのルータを使っていなければ`nil`にするらしい

ここで少し僕的に複雑だったHTTPのあれこれと`HandleFunc`などについて詳しく調べて簡単にまとめてみます。興味のない方は飛ばしてね！！！

####HandleFuncとかHandlerとか
[ここにまとめられているのをみるといいかも](https://qiita.com/nirasan/items/2160be0a1d1c7ccb5e65)

httpパッケージに置いて`http.Hadler`はHTTPリクエストに対応してレスポンスを返す。

`http.Handle`はURLに対応する`http.Hadler`を登録します。

`http.HandlerFunc`は`ServeHTTP`を持っているのでこれだけで`http.Hadler`を用意できます。

`http.HandleFunc`はなんか登録します。

あまりよくわからないからまだまだ調べてみる必要がありそう。

**メインでmuxを使って行ったことは`http.HandleFunc`と同じことをしているらしい。
リクエストされたURLがパスにマッチしたら`(http.ResponseWriter, *http.Request)`をパラメーターとしてハンドラーを呼び出します。**

####動作確認
`go run main.go`

走らせてみます。

`http://localhost:8081`で`Hello! I'm ok `が表示されました！！

とりあえず無事ルートは確立できてるようです。

同じ要領でとりあえずパスを簡単なファンクションに紐付けてどんどんつくってしまいます。

 - 他のパス

新しく`todo.go`を作ります。

```todo.go
package main

import (
	"fmt"
	"net/http"
)

func GetTodos(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "This is a Todos list")
}

func CreateTodo(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Successfully created new Todo")
}

func UpdateTodo(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Successfully updated Todo")
}

func DeleteTodo(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Destroyed that disgusting Todo")
}
```
さっきと同じでそれぞれの違ったテキストを入れました。

動作確認をしましょう。

####動作確認

動作確認には**Postman**を使います。

**Postman**はAPI構築の大きな助けになる便利なツールです！！
今回はHTTPリクエストとそれに対するリスポンスがちゃんと動作しているかを確認するのに使います。

[初めての方はインストールしてみてください](https://www.getpostman.com/downloads/)

<img width="1276" alt="Screenshot 2019-05-12 17.09.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412949/965aaacb-4efd-84ea-48cb-b3daa658eeaa.png">

メソッドの指定やURLの指定ができ、レスポンスが下の画面に現れます。

早速、`go run .go`で走らせて、リクエストを送ってみます。

<img width="1276" alt="Screenshot 2019-05-12 20.56.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412949/6c6b5fd6-1dd1-f04b-c380-617fe957927f.png">

<img width="1276" alt="Screenshot 2019-05-12 20.56.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412949/aaf20afd-1a8e-9d05-2f1c-4bc2ee4fcfd8.png">

うまくできました！
他のもうまくできました！

ルートは無事マッピングできたようです！

##まとめ
長くなりそうなので今回はここで区切って
次にORMを使ったデータの実装をしてみたいと思います。

サーバの確立は比較的簡単に実装できますね。
ただhttpのあれこれを完璧に理解しているかと言われると理解していないのでまだまだ研究が必要。