Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

GoでAPIをシュッと書く

More than 1 year has passed since last update.

この記事は 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系の処理なんかをまとめることもできちゃったりします。便利ですね。

まとめ

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

sys_cat
Perl初心者 Ruby,PHP,JavaScript時々Python,Golang
http://sys-cat.github.io/
gamewith
GameWithは、ゲームをプレイされる皆様がより深くゲームを楽しんで頂ける環境を提供するべく設立されました。あなたがゲームをする時のお供になる。これが私達の目標です。
https://gamewith.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away