GO言語 “Gin”と”xorm”でAPI作成してみた

#環境整備
OS : macOS Mojave(10.14.2)
####GO言語のインストール(Homebrew)
```
brew install go
go version // go version go1.10.3  darwin/amd64
```
####WEBフレームワーク"GIN"インストール
```
go get -u github.com/gin-gonic/gin
```
####ORマッパー"xorm"インストール
```
go get -u github.com/go-xorm/xorm
```
####PostgreSQLインストール
```
brew install postgresql
psql --version //psql (PostgreSQL) 10.4
```
#API 作成手順
```
ディレクトリ構造
api/
  ┠main.go
  ┃
  ┠controllers/
  ┃         ┗animal_controllers.go
  ┃
  ┠models/
        ┗animals.go
```

##1.まずは、API用のDB作成を行います
``` 
#起動
$ postgres -D /usr/local/var/postgres

#DB作成(PostgreSQLを起動しているタブとは別タブで行う)
$ createdb animals

#DB確認
$ psql -l
                                           List of databases
   Name    |     Owner      | Encoding |   Collate   |    Ctype    |         
-----------+----------------+----------+-------------+-------------+----
 animals   | username       | UTF8     | en_US.UTF-8 | en_US.UTF-8 |

#ログイン
$ psql animals

#テーブル作成
animals=# CREATE TABLE animals(id SERIAL,name varchar(50),habitat varchar(50));

#テーブル表示
animals=# \d animals
                                    Table "public.animals"
 Column  |         Type          | Collation | Nullable |               Default
---------+-----------------------+-----------+----------+-------------------------------------
 id      | integer               |           | not null | nextval('animals_id_seq'::regclass)
 name    | character varying(50) |           |          |
 habitat | character varying(50) |           |          |

#xormアクセス用ユーザの新規作成
animals=# create user animal_owner WITH PASSWORD '1234567'

#animals、animals_id_seqテーブルに対する、animal_ownerに権限付与
animals=> GRANT SELECT, UPDATE, INSERT ON animals TO animal_owner;
animals=> GRANT SELECT, UPDATE, INSERT ON animals_id_seq TO animal_owner;
animals=> GRANT SELECT ON SEQUENCE animals_id_seq to animal_owner;
 
# \z で権限確認

#先程作成したユーザでログインできるか確認
 - ログアウト
　\q
 - ログイン
　 psql -U animal_owner -d animals

#試しにデータを挿入(insert)し、確認します
animals=> insert into animals(name,habitat) values('rabbit','JAPAN');
animals=> select * from animals;
 id |  name  | habitat
----+--------+---------
  1 | rabbit | JAPAN
(1 row)

以上でDB周りの準備は、Okayです！！
```

##2.controllerを作成します
今回はDBに登録されている動物全部を返す"Index"と新規登録用の"Create"関数を作成します

``` go:animal_controllers.go
package animal_controllers

import (
	"fmt"
	"log"
    "github.com/gin-gonic/gin"
    "github.com/go-xorm/xorm"
    "../models"
)

func Index(c *gin.Context) {
    url := "user=animal_owner host=localhost port=5432 dbname=animals sslmode=disable"
    engine, err := xorm.NewEngine("postgres", url)
    if err != nil {
        log.Fatal(err)
        fmt.Println(err)
    }else{
      results, err := engine.QueryString("select * from animals")
      if err != nil {
        log.Fatal(err)
        fmt.Println(err)
      }else{
        fmt.Println(len(results))
        
        c.JSON(200, results)
      }
    }


}

func Create(c *gin.Context) {
  newAnimal := models.Animals{}
  fmt.Println(c)
  c.Bind(&newAnimal)
  fmt.Println(newAnimal.Name)
  url := "user=animal_owner host=localhost port=5432 dbname=animals sslmode=disable"
  engine, err := xorm.NewEngine("postgres", url)
  if err != nil {
    log.Fatal(err)
  }
    engine.Insert(&newAnimal)
    c.JSON(200, "Created!")
}
```
##3. modelの作成を行う
```go:animals.go
package models

import (
  _ "github.com/lib/pq"
)
type Animals struct {
  Name string 
  Habitat string
}
```
##4.ルーティング設定(main.go)
```go:main.go
package main

import (
    "github.com/gin-gonic/gin"
    "./controllers"
)

func main() {
    router := gin.Default()
    router.GET("/animals", animal_controllers.Index)
    router.POST("/animal", animal_controllers.Create)
    router.Run(":5000")
}
```
##5.curlコマンドで確認
curlコマンド実行前に、まずはmain.goを実行します

```
$ go run main.go
```
```
GET(curlコマンド)

curl -H 'application/json' 'localhost:5000/animals'

レスポンス

[{"habitat":"JAPAN","id":"1","name":"rabbit"}]

```

```
POST(curlコマンド)

curl -X POST -H "Content-Type: application/json" 
-d '{"name":"kangaroo", "habitat":"Australia"}' localhost:5000/animal

レスポンス
"Created!"

```

DB上で挿入(Insert)されたか確認(連番になってないのは、筆者がミスってDELETEしたため)

```
animals=> select * from animals;
 id |   name   |  habitat
----+----------+-----------
  1 | rabbit   | JAPAN
  4 | kangaroo | Australia
(2 rows)
```

挿入(Insert)できてますね！！ 
"Gin"と"xorm"を使用することで簡単にAPIの作成ができました


#所感
普段はrailsで開発をしており、初めてGo言語に触れ、コンパイルチェックが厳しい言語だと感じた（コンパイルチェックが厳しいことは良いこと）