うごく生ゴミプログラマの備忘録

うごく生ゴミ 〜再臨〜

Go言語でAPI作った話

書くこと

  • Go言語でRestAPIつくりましたって話

  • 参考にした本とか記事とか

  • 環境構築とか

  • 書いたソースと簡単な説明とか

  • その他感想とか

Go言語でRestAPI作りましたって話

RestAPIって言っても、ランダムに運勢をJSON形式で返すだけの おみくじAPIです。 GETメソッドで omikuji.json を叩くと運勢が帰ってきます。 ブラウザで直接開いた場合以下のような感じです。まんまJSONです。

f:id:jBellTree:20160516083509p:plain

参考にした本とか記事とか

まず一通り基本的な文法とか、お作法的なところを↓の本で勉強しました。 ちなみに今回はKindle版を買った。検索は対応してるっぽいです。

https://www.amazon.co.jp/%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0Go%E8%A8%80%E8%AA%9E-%E6%9D%BE%E5%B0%BE%E6%84%9B%E8%B3%80-ebook/dp/B01FH3KRTI?ie=UTF8&qid=&ref_=tmm_kin_swatch_0&sr=www.amazon.co.jp

で、RestAPI作りたいなーって思ったら以下の記事を見つけたので参考にさせていただきました。

qiita.com

環境構築とか

上の記事で使用されている go-json-rest なるライブラリを使いましょうという方針でいく。 が、俺の環境にはまだそんなライブラリを落としてきていない。ので落としてくるのだが、じゃあどうやるのかというと、 俺は↓の記事を参考に ghq なる物をインストールし、ghqを使用して go-json-rest をインストールしました。

ghq... 連合国軍総司令部???

qiita.com

書いたソースと簡単な説明とか

構成

パッケージ構成は以下のようにしました。 ソース内の packaege ~~~ も実際のフォルダ構成と同じ。

main
 ├ bin/
 └ main/
     ├ OmikujiApi.go
     │
    ├ data/
     │  └ OmikujiData.go
     │
      └ resource
          └ Omikuji.go

OmikujiApi.go

なんかいろいろやってる。 go-json-rest ライブラリのAPIをちゃんと読まないといけないんだけど、 たぶん、 * 受け付けるメソッドの設定(GETとかPOSTとかDELETEとか)、 * パスのルーティング(? っていう言葉でいいのかな) http:// ... /omikuji.json というパスとそのパスにアクセスされた場合に実行する処理の紐付け * 何番のポートを使うかの設定 (今回は 8081番)

をやっている。(つもりになってます。)

package main

import (
    "net/http"
    "github.com/ant0ine/go-json-rest/rest"
    "./resource"
    "log"
)


func main() {

    api := rest.NewApi()
    api.Use(rest.DefaultDevStack...)
    api.Use(&rest.CorsMiddleware{
        RejectNonCorsRequests: false,
        OriginValidator: func(origin string, request *rest.Request) bool {
            return true
        },
        AllowedMethods: []string{"GET"},
        AllowedHeaders: []string{
            "Accept", "Content-Type", "X-Custom-Header", "Origin"},
        AccessControlAllowCredentials: true,
        AccessControlMaxAge:           3600,
    })
    router, err := rest.MakeRouter(
        rest.Get("/omikuji.json", resource.GetOmikuji),
    )
    if err != nil {
        log.Fatal(err)
    }
    api.SetApp(router)
    log.Fatal(http.ListenAndServe(":8081", api.MakeHandler()))
}

OmikujiData.go これが実際にJSON形式にして返すデータ。 SetUnsei() を使うと運勢がランダムにセットされる。

package data

import (
    "time"
    "math/rand"
)


type OmikujiData struct {
    Unsei string
}

func (omikujiData *OmikujiData) SetUnsei() {

    unseiMap := map[int]string{
        0: "大吉",
        1: "中吉",
        2: "小吉",
        3: "末吉",
        4: "吉",
        5: "凶",
        6: "末凶",
        7: "小凶",
        8: "中凶",
        9: "大凶",
    }

    rand.Seed(time.Now().UnixNano())
    unsei := unseiMap[rand.Intn(10)]
    omikujiData.Unsei = unsei
}

Omikuji.go

OmikujiData構造体をJSONにして返す関数を書いた。

package resource

import (
    "github.com/ant0ine/go-json-rest/rest"
    "../data"
)


func GetOmikuji(w rest.ResponseWriter, r *rest.Request) {

    omikujiData := new (data.OmikujiData)
    omikujiData.SetUnsei()
    w.WriteJson(omikujiData)
}

その他感想とか

正直、ここまでめっちゃスムーズにできたと思う。 JavaJAX-RSのプロジェクト作って、RestAPIの動作確認まで…とかと比べてだけど。 たぶん Go言語の方がずっと詰まるところが少なかったと思う。

動作が確認できるまでの途中途中での、「なんかうまくいかないんだが?」っていうのってモチベーションの維持に非常に関わるので、 そういうのが少ないのって素晴らしいと思う。まる。