はじめに
簡単なAPIサーバを作成したいと思います。
Goを使い始めてまだ浅いので間違っている部分があるかもしれませんがご容赦ください。
プロジェクトの作成
今回は、go-api-server
という名前にします。[username]
は自身の名前で。
$ mkdir $GOPATH/src/github.com/[username]/go-api-server
$ cd go-api-server
Herokuの準備
Herokuに登録する。
Herokuのコマンドラインツールをインストール。
インストールが終わったら、下記コマンドを実行。
$ heroku login
HerokuにNew Appを作成。
$ heroku apps:create go-api-server --buildpack heroku/go
Gitの設定も行います。
$ git init
$ heroku git:remote -a go-api-server
MySQLの準備
HerokuでMySQLを使うには、クレジットカードの登録が必要。
クレカ登録参考: http://wp.developapp.net/?p=5250
以下のコマンドを使ってClearDBアドオンを追加して、データベースの設定をMySQLに変更。
$ heroku addons:add cleardb
ファイルの作成
フレームワークはecho、ORMはgormを使用していきます。
他にも、
github.com/go-sql-driver/mysql
-
github.com/labstack/echo/middleware
などを使用するので、必要に応じてgo get
しておいてください。
main.goの作成
環境変数"PORT"を使用するので、osをインポートします。
まだ、dbを宣言していなかったり、Productを作成していないので、エラーになるかもしれませんが、後に作成していきます。
package main
import (
"log"
"net/http"
"os"
_ "github.com/go-sql-driver/mysql"
"github.com/labstack/echo"
"github.com/labstack/echo/middleware"
)
func main() {
defer db.Close()
port := os.Getenv("PORT")
if port == "" {
log.Fatal("$PORT must be set")
}
e := echo.New()
// middleware
e.Use(middleware.Logger())
// routing
e.GET("/products", indexProduct)
e.GET("/products/:id", showProduct)
e.POST("/products", createProduct)
e.Logger.Fatal(e.Start(":" + port))
}
func indexProduct(c echo.Context) error {
var products []Product
db.Find(&products)
jsonObject := map[string][]Product{"products": products}
return c.JSON(http.StatusOK, jsonObject)
}
func showProduct(c echo.Context) error {
var product Product
db.First(&product, c.Param("id"))
return c.JSON(http.StatusOK, product)
}
func createProduct(c echo.Context) error {
product := Product{Code: "ABCDEF", Price: 1000}
db.Create(&product)
return c.JSON(http.StatusOK, product)
}
database.goの作成
データベース設定関係のファイルを作成していきます。
変数datasourceの中身についてはまず、下記コマンドを入力。
$ heroku config | grep CLEARDB_DATABASE_URL
CLEARDB_DATABASE_URL: mysql://38faf8fefeaaef:dfefe44@us-cdbr-iron-east-093823.cleardb.net/heroku_8cfefedfgcd6a?reconnect=true
// 出力された`CLEARDB_DATABASE_URL`の値を`DATABASE_URL`に格納
$ heroku config:set DATABASE_URL='mysql://38faf8fefeaaef:dfefe44@us-cdbr-iron-east-093823.cleardb.net/heroku_8cfefedfgcd6a?reconnect=true'
出力された、CLEARDB_DATABASE_URLの内容
mysql://38faf8fefeaaef:dfefe44@us-cdbr-iron-east-093823.cleardb.net/heroku_8cfefedfgcd6a?reconnect=true
から、mysql://
、?reconnect=true
を取り除く。そして、Host部分をtcp()
で囲む。また末尾に?parseTime=true
を追加。
38faf8fefeaaef:dfefe44@tcp(us-cdbr-iron-east-093823.cleardb.net:3306)/heroku_8cfefedfgcd6a?parseTime=true
package main
import (
"fmt"
"os"
"github.com/jinzhu/gorm"
)
var db *gorm.DB
func init() {
var err error
var datasource string
if os.Getenv("DATABASE_URL") != "" {
// Heroku用
datasource = "[username]:[password]@tcp([host]:3306)/[database]?parseTime=true"
} else {
// ローカル用
datasource = "[username]:[password]@/[database]?parseTime=true"
}
db, err = gorm.Open("mysql", datasource)
if err != nil {
panic("failed to connect database")
}
db.AutoMigrate(&Product{})
}
product.goの作成
Productモデルを定義していきます。
gorm.Modelには、ID
、CreatedAt
などの基本的な情報が定義されています。
package main
import "github.com/jinzhu/gorm"
type Product struct {
gorm.Model
Code string
Price uint
}
Procfileの作成
Herokuでは、Procfile
というファイルが必要らしいので追加します。
web: go-api-server
各依存パッケージ管理方法
今回は、govendor
というツールを使用します。
// インストール
$ go get -u github.com/kardianos/govendor
// 初期化
$ govendor init
// 設定ファイルの更新と依存パッケージの vendor へのダウンロード
$ govendor fetch +out
デプロイ
$ git add .
$ git commit -m "comment"
$ git push heroku master
デプロイされたか確認します。
$ heroku open products
確認できれば完成です。
おそらく初めて立ち上げたときには、まだデータがないので、以下のようなjsonが帰ってくると思います。
{
products: []
}
/productsにPOSTするとデータが増えていきます。
ただ、IDが10ずつインクリメントされていきます。
参考記事: herokuでmysql(ClearDB)を使うとidが10ずつ増える
終わりに
久しぶりにHerokuを使いましたが便利ですね。
もっとGoを使いこなせるようになりたいです。
参考文献
- Getting Started on Heroku with Go
- ClearDB MySQL
- HerokuでGoアプリケーションを動かしたい
- [Heroku への Go 言語製アプリケーションのデプロイと依存パッケージ管理方法の比較] (http://qiita.com/nirasan/items/32f2e0fc94ccf123ca55)
- labstack/echo
- jinzhu/gorm