miyazi888の覚え書き日記

学習したことを書き留めてます。

echoでリクエストパラメータを構造体に割り当てる

昨日のブログでリクエストパラメータの取得方法はわかりました。
ただ、昨日のやり方ではパラメータを一つ一つ変換するコードを書かないといけません。
Railsであれば、ParamにHashですべて格納されているので悩む必要もないのですが・・・

昨日のブログ
http://miyazi888.hatenablog.com/entry/2019/08/11/201510

そこで公式を調べてみた所、Bindという機能がechoでは提供されていて、これはリクエストパラメータを構造体に割り当てるもののようでした。
さっそく試してみました。

パラメータを構造体に変換

今回のサンプルではName,Priceというフィールドを持つItemという構造体を用意して、その構造体にリクエストパラメータを割り当てます。
割り当てる方法は構造体にアノテーションを定義してそこにリクエスト内の変数名を指定することで、割り当てを定義できます。
その上でBind関数を使うことで割当完了です。

プログラム

package main

import (
    "net/http"
    "strconv"

    "github.com/labstack/echo"
)

type Item struct {
    Name  string `json:"name" form:"name" query:"name"`
    Price int    `json:"price" form:"price" query:"price"`
}

func main() {
    e := echo.New()
    e.GET("/items", getItems)
    e.POST("/item", createItem)
    e.Logger.Fatal(e.Start(":1111"))
}

func getItems(c echo.Context) error {
    item := new(Item)
    if err := c.Bind(item); err != nil {
        return nil
    }
    return c.String(http.StatusOK, "name = "+item.Name+" price = "+strconv.Itoa(item.Price))
}

func createItem(c echo.Context) error {
    item := new(Item)
    if err := c.Bind(item); err != nil {
        return nil
    }
    return c.String(http.StatusOK, "name = "+item.Name+" price = "+strconv.Itoa(item.Price))
}

実行

go run main.goでサーバを起動した後、curlコマンドで動作確認します。
上からjson、form、queryでnameとpriceを渡すコマンドで、それぞれのやり方で正しく構造体にデータが割あたっていることがわかります。

curl -X POST http://localhost:1111/item -H 'Content-Type: application/json' -d '{"name":"title1", "price": 123}' > name = title1 price = 123
curl -X POST localhost:1111/item -d 'name=item1' -d 'price=123' > name = item1 price = 123
curl http://localhost:1111/items\?name\=title1\&price\=123  > name = title1 price = 123