EchoのBindでクエリとパスパラメータを構造体に入れる方法
始めに
普段GoでAPIを作るときはよくEchoを使っていますが、 コードリーディングしたらクエリとパスパラメータを構造体にサクッと入れる機能を知ったので紹介します。
前提知識
Echo
では次のやり方で値を取得できます。
e.Param(key)
でパスパラメータe.QueryParam(key)
でクエリパラメータクエリパラメータ
// curl localhost/users?name=gorilla
func(c echo.Context) error {
name := c.QueryParam("name")
// gorilla
fmt.Println(name)
...
}
- パスパラメータ
// curl localhost/users/gorilla
e := echo.New()
e.GET("/users/:name", func(c echo.Context) error {
name := c.Param("name")
// gorilla
fmt.Println(name)
})
例
- API定義は
PUT /users/:id
- リクエストボディは
{"name": "xxx"}
という定義になっているとします。
その場合、次の処理をします。
c.Param()
でパスパラメータからidを取得c.Bind()
でリクエストボディからは更新データを取得- idとnameを構造体に入れて、O/RマッパのUpdateを使って更新
type User struct {
ID int `json:"id"`
Name string `json:"name"`
}
e.PUT("/users/:id", func(c echo.Context) error {
id := c.Param("id")
var u User
if err := c.Bind(&u);err != nil {
// error handling
}
u.ID = id
db.Update(&u)
...
})
やり方
ただ、これだとidとnameのデータ取得方法がそれぞれ異なるのでチョット面倒です。
そこで、構造体にquery
or param
をつけてc.Bind
すればEcho
がよしなに
クエリパラメータorパスパラメータを構造体に入れてくれます。
次の例はparam
をつけてパスパラメータのidを取得しています。
type User struct {
ID int `json:"id" param:"id"`
Name string `json:"name"`
}
e.PUT("/users/:id", func(c echo.Context) error {
var u User
if err := c.Bind(&u);err != nil {
// error handling
}
db.Update(&u)
...
})
雑感
一応この機能は公式ガイドに書いてありましたが、コードリーディングして見つけました… ちゃんと公式ドキュメントを読もうねって気持ちになりました。