Posted at
GameWithDay 23

GoでAPIをシュッと書く

この記事は GameWith Advent Calendar 2018 の23日目です。Adventも終わりかーと思うともう目の前にはお正月ですね。1年も早いものですね。

今回もGolangです、周りがPHPばかりですが挫けずやっていきましょう。


前段

Golang、基本的に社内ではCLIツールを作成するのに使う事が多いのですが個人的な趣味でAPIもGolangで書くことが多いです。

今回はAPIをシュッと書いていこうぜという感じです。


Framework

Golangの世界では「Frameworkを使わなくてもスリムに書けるぜ」というお話をよくお見かけしますし、たまに使わずに書く事もありますがあるものは使っていきましょう。

私は普段このWebFrameworkを使っています。

他にもGinなど使う事も多いのですがなんだかんだ私はこちらを使うことが多いです。

程よい薄さが良い。といえば良いのでしょうか…?


Get Starting

ドキュメントは基本的に英語ですがコードがスッキリしているのである程度読めちゃったりします。

package main

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

func main() {
e := echo.New()
e.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, "Hello")
})
e.Logger.Fatal(e.Start(":8080"))
}

実質5行ですね。基本的にVer3以降のechoはほとんど net/http への薄いラッパーです。

実際に echo.New() で返却される Echo 構造体の中身を見ると この様になっています。実質 net/http では?(錯乱


Routingを少しちゃんとする

上の例ではMainの中でRouting設定も行っています。ただこれだとRoutingが増えるたびにMainの中身が大きく膨れ上がってしまいます。

なのでこんな感じに。

package main

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

func main() {
e := echo.New()
e.GET("/", hello)
e.Logger.Fatal(e.Start(":8080"))
}

func hello(c echo.Context) error {
return c.String(http.StatusOK, "Hello")
}

他にも別ファイルに設定を配置するなどの方法がありますが簡単に書くならこんなところでしょうか。


RoutingRule とか

他のフレームワークにもあるようにPathParameterをいじる事も出来ます。

func main() {

e := echo.New()
e.GET("/:id", hello)
e.Logger.Fatal(e.Start(":8080"))
}

func hello(c echo.Context) error {
id := c.Param("id")
return c.String(http.StatusOK, "Hello "+id)
}

他にもGroupの機能が admin := e.Group("/admin") の様に設定出来たり

Methodも GET, POST, DELETE, PUTのように指定出来ます。必要最低限ですね。


JSON を返す

これで簡単に文字列を返すところまでいけました。ではAPIらしくJSONでResponseを返しましょう。

基本的にはRequest毎に構造体を宣言する必要があります。

package main

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

type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}

func main() {
e := echo.New()
e.GET("/", hello)
e.Logger.Fatal(e.Start(":8080"))
}

func hello(c echo.Context) error {
user := &User{
ID: 100,
Name: "sample user",
Email: "sample@test.com",
}
return c.JSON(http.StatusOK, user)
}

返却時はこんな感じ。

{

id: 100,
name: "sample user",
email: "sample@test.com"
}

構造体にアノテーションを付与することで返却時のキーを定義する事が出来ます。簡単ですね。


他の機能とか

APIの開発をするとなると共通系のOAuthやLogger、CORSなどが必要だったりします。そんなときはMiddleware機能を利用すると良いです。

e.Use(middleware.Logger())

e.Use(middleware.CORS())

Middlewareは自前で実装することも出来るのでOAuth系の処理なんかをまとめることもできちゃったりします。便利ですね。


まとめ

もっと書きたい事は沢山あったのですがとりあえずはこんなところで。