# はじめに

FundastA Inc.の片田です!

この度、クリエイターズラボさんのオンライン勉強会に参加させていただきまして、

Golangに入門しました!

Golangを書く楽しさに目覚めてしまったので、Golangで簡単なAPIを作ってHerokuにさくっとデプロイする手順をまとめておきます。

# Golangとは

公式ドキュメントはこちら

GolangはGoogleが開発してる言語で云々。。

というのはいくらでも説明されているので、本記事では省きます。

めっちゃ軽くてめっちゃ書きやすい言語なんだなあ〜って思ってます。

# Golangでできること

  • WEBアプリケーション開発
  • モバイルアプリケーション開発
  • IoT分野での組み込み系システム開発

他にも様々な使われ方がされているらしいです。

本当になんでもできる。。

# Golangのメリット・デメリット

# メリット

  • 処理が高速
  • コンパイルも早い
  • シンプルな記述ができる
  • ある程度制約があるため、チーム開発でも用いやすい

# デメリット

  • ジェネリックや継承など、言語仕様的に物足りない部分もある
  • Golangエンジニアの数が少ない

# Golangでサーバーを立ててみる

軽量のWEBサーバー立てられるライブラリ

  • echo (https://echo.labstack.com/guide)

上記のechoというライブラリを使えば、一瞬で簡単なREST APIが作れちゃいます。

echoライブラリをgogetしたら、下記のように記述するだけでサーバーが立てられます。

import (
    "net/http"
	"os"
    
    "github.com/labstack/echo"
)

func main() {
    // サーバーのインスタンス作成
    e := echo.New()
    
    // ルーティング設定
    e.GET("/", helloworld)
    
    // サーバー起動
	e.Logger.Fatal(e.Start(":" + os.Getenv("PORT")))
}

func helloworld(c echo.Context) error {
    return c.String(HttpStatus.OK, "Hello, World")
}

起動コマンドは一応、こちらです。

go run main.go

これでサーバーを起動すれば、ルートにGETリクエストを投げるとHello, Worldという文字列(JSON)が返ってくるAPIが作れました!

# GolangでDB操作をする

DB操作に使えるライブラリ

  • GORM (https://gorm.io/ja_JP/docs/index.html)

次に値をDBに保存、取得して表示する処理を追加していきましょう。

import (
    "github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/sqlite"
    "github.com/labstack/echo"
)

type Content struct {
	gorm.Model
	Text    string `json:"text"`
}

// DBのインスタンスをグローバル変数に格納
var (
	db *gorm.DB
)

func main() {
    // DB接続処理
    var err error
    db, err = gorm.Open("sqlite3", "/tmp/gorm.db")
    if err != nil {
        panic("failed to connect database")
    }
    // サーバーが終了したらDB接続も終了する
    defer db.Close()
    
    // スキーマのマイグレーション
    db.AutoMigrate(&Content{})
    
    // レコード登録
    db.Create(&Content{Content: "Hello, World"})
    
    // レコード全取得
    db.Find(&Content)
}

GORMはORMなので、SQL文を書かなくてもDB操作をすることができます。

GORMを使えば上記のように、超簡単にDB操作ができるので、私のように初見でも問題なく理解できてしまいます。。すごい。。

これを上記のコードと組み合わせたコードがこちらです。

import (
    "net/http"
	"os"
    
    "github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/sqlite"
    "github.com/labstack/echo"
)

type Content struct {
	gorm.Model
	Text    string `json:"text"`
}

// DBのインスタンスをグローバル変数に格納
var (
	db *gorm.DB
)

func main() {
    // DB接続処理
    var err error
    db, err = gorm.Open("sqlite3", "/tmp/gorm.db")
    if err != nil {
        panic("failed to connect database")
    }
    // サーバーが終了したらDB接続も終了する
    defer db.Close()
    
    // サーバーのインスタンス作成
    e := echo.New()
    
    // ルーティング設定
    e.GET("/contents", getAllContents)
    e.POST("/create", createContent)
    
    // サーバー起動
    e.Logger.Fatal(e.Start(":" + os.Getenv("PORT")))
}

func createContent(c echo.Content) error {
    // レコード登録
    db.Create(&Content{Text: "newText"})
    return c.String(http.StatusOK, "record created")
}

func getALlContent(c echo.Content) error {
    var content Content
    // contentテーブルのレコードを全件取得
    db.find(&content)
    // 取得したデータをJSONにして返却
    return c.JSON(http.StatusOK, content)
}

# 【下準備】Golang製のAPIをHerokuにデプロイする

herokuでgo apiをビルドするために必要なもの

  • go.mod → バージョン管理
  • Procfile → heroku独自のconfigファイル
  • GitHubリポジトリ → herokuデプロイの際に必要

herokuでGo製のAPIを動かすためには、ローカルでは必要なかったファイルをいくつか作成する必要があります。

順番にみていきましょう。

# go.modについて

まずはgo.modと呼ばれるGoのバージョン管理ライブラリを導入します。

これがないと、herokuにデプロイする際に、ビルドで失敗してしまいます。

go.modファイルを作成することで、ライブラリのバージョンを定義しておけるので、それによってheroku上のサーバーでビルドすることが可能になります。

go.modの使い方はこちらの記事に詳しく載っています。

ざっくりいうと、プロジェクトのルートディレクトリで下記のコマンドを叩くだけです。

go mod init

これでgo.modの準備は完了しました!

# Procfileについて

Procfileについては公式ドキュメントがあります。

ざっくりいうと、heroku上でアプリを動かすのに必要なファイルです。

詳しい書き方までは今回調べませんでしたので、詳細はドキュメントをご覧ください。

今回はルートディレクトリ直下にProcfileを作成し、コンパイルしたファイルのパスを指定するのみです。

web: bin/first_go_api(作成したgitリポジトリ名)

# GitHubリポジトリについて

GitHubについての詳しい説明は省きます。

herokuはGitHubのリポジトリを参照してデプロイを行うので、リポジトリ作成しようねって話みたいです!

上述した通り、リポジトリ名はProcfileで指定する必要があるので、わかりやすい名前を付けましょう。

# 【実作業】Golang製のAPIをHerokuにデプロイする

では実際にデプロイしていきます。

当記事はherokuの記事ではないので、詳細な手順はググってみてください。

一応、herokuの公式ドキュメントはこちら

heroku cliからデプロイするのが簡単かなあと思います。

Dockerで環境構築してても簡単にデプロイできるみたいです。

デプロイが終わったら、curlコマンドを叩いて確認してみましょう!

POSTメソッド(レコード登録)↓

curl -X POST -H "Content-Type: application/json" -d '{"Text":"newText"}' https://<アプリのURL>/create

レスポンスは下記の通りです。

"record created"

続いてGETメソッド(レコード取得)↓

curl 'https://<アプリのURL>/contents'

レスポンスは下記の通りです。

{
    "Value": {
        "ID": 1,
        "CreatedAt": "2020-04-19T00:05:09.494982+09:00",
        "UpdatedAt": "2020-04-19T00:05:09.494982+09:00",
        "DeletedAt": null,
        "Text": "newText",
    },
    "Error": null,
    "RowsAffected": 1
}

ちゃんと取れてますね。

# おわりに

お仕事ではJavaがメインですが、Goの書きやすさ、分かりやすさには感動しました。。

趣味のプロダクトは、バックエンドはnode.jsで書くことが多いですが、これからはGoも視野に入れて技術選択していきたいです。

また、2020/4/19現在から2020/5/31までの期間限定で、メルカリのGo学習教材が無料公開されています。

気になる方はぜひ覗いてみてください!!

プログラミング言語Go完全入門