LoginSignup
27
15

More than 5 years have passed since last update.

Heroku+echo(go)+MySQLでJSON APIサーバを立ててみる

Posted at

はじめに

簡単なAPIサーバを作成したいと思います。
Goを使い始めてまだ浅いので間違っている部分があるかもしれませんがご容赦ください。

プロジェクトの作成

今回は、go-api-serverという名前にします。[username]は自身の名前で。

Terminal
$ mkdir $GOPATH/src/github.com/[username]/go-api-server
$ cd go-api-server

Herokuの準備

Herokuに登録する。

Herokuのコマンドラインツールをインストール
インストールが終わったら、下記コマンドを実行。

Terminal
$ heroku login

HerokuにNew Appを作成。

Terminal
$ heroku apps:create go-api-server --buildpack heroku/go

Gitの設定も行います。

Terminal
$ git init
$ heroku git:remote -a go-api-server

MySQLの準備

HerokuでMySQLを使うには、クレジットカードの登録が必要。
クレカ登録参考: http://wp.developapp.net/?p=5250

以下のコマンドを使ってClearDBアドオンを追加して、データベースの設定をMySQLに変更。

Terminal
$ 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を作成していないので、エラーになるかもしれませんが、後に作成していきます。

main.go
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の中身についてはまず、下記コマンドを入力。

Terminal
$ 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を追加。

変数datasource
38faf8fefeaaef:dfefe44@tcp(us-cdbr-iron-east-093823.cleardb.net:3306)/heroku_8cfefedfgcd6a?parseTime=true
database.go
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には、IDCreatedAtなどの基本的な情報が定義されています。

product.go
package main

import "github.com/jinzhu/gorm"

type Product struct {
    gorm.Model
    Code  string
    Price uint
}

Procfileの作成

Herokuでは、Procfileというファイルが必要らしいので追加します。

Procfile
web: go-api-server

各依存パッケージ管理方法

今回は、govendorというツールを使用します。

Terminal
// インストール
$ go get -u github.com/kardianos/govendor

// 初期化
$ govendor init

// 設定ファイルの更新と依存パッケージの vendor へのダウンロード
$ govendor fetch +out

デプロイ

Terminal
$ git add .
$ git commit -m "comment"
$ git push heroku master

デプロイされたか確認します。

Terminal
$ heroku open products

確認できれば完成です。
おそらく初めて立ち上げたときには、まだデータがないので、以下のようなjsonが帰ってくると思います。

json
{
   products: []
}

/productsにPOSTするとデータが増えていきます。
ただ、IDが10ずつインクリメントされていきます。
参考記事: herokuでmysql(ClearDB)を使うとidが10ずつ増える

終わりに

久しぶりにHerokuを使いましたが便利ですね。
もっとGoを使いこなせるようになりたいです。

参考文献

27
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
15