miyazi888の覚え書き日記

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

echoでリクエストパラメータをチェックするには

echoでリクエストパラメータを取得し、構造体に割り当てる方法はわかったのですが、ここまで出来ると今度はvalidateの方法が知りたくなり、調べてみました。
echoにはvalidateそのものは用意されていないのですが、インターフェイスだけが用意されていて、このインターフェイスに合わせて実装していくようです。 公式にはサンプルとして、有名なバリデーションライブラリであるところのvalidatorを使ったサンプルがあったので、これを打ち込んで検証してみました。

https://github.com/go-playground/validator

プログラム

Validateというメソッドを持った関数をechoに登録し、必要なところでValidate(構造体ポインタ)を渡す感じで呼び出すのが基本のようです。
今回であれば、CustomValidatorという構造体を登録しています。
validatorは構造体のアノテーションにvalidateしたい内容を記述していくスタイルです。今回は必須項目チェックを行うので、requiredをアノテーション内で指定しています。

package main

import (
    "net/http"

    "github.com/labstack/echo"
    "gopkg.in/go-playground/validator.v9"
)

type User struct {
    Name string `json:"name" validate:"required"`
}

type CustomValidator struct {
    validator *validator.Validate
}

func (cv *CustomValidator) Validate(i interface{}) error {
    return cv.validator.Struct(i)
}

type Error struct {
    Error string `json:"error"`
}

func main() {
    e := echo.New()
  // validatorを登録
    e.Validator = &CustomValidator{validator: validator.New()}
    e.POST("/", test)
    e.Logger.Fatal(e.Start(":1111"))
}

func test(c echo.Context) error {
    u := new(User)
  // ここでリクエストパラメータを構造体に
    if err := c.Bind(u); err != nil {
        return c.JSON(http.StatusBadRequest, err)
    }
  // Validateを実施
    if err := c.Validate(u); err != nil {
        return c.JSON(http.StatusBadRequest, &Error{Error: err.Error()})
    }
    return c.JSON(http.StatusOK, u)
}

実行

JSON形式でNameに対して空文字を送信するとエラーとなります。

curl -X POST http://localhost:1111 -H 'Content-Type: application/json' -d '{"Name":""}'
{"error":"Key: 'User.Name' Error:Field validation for 'Name' failed on the 'required' tag"}

curl -X POST http://localhost:1111 -H 'Content-Type: application/json' -d '{"Name":"test"}'
{"name":"test"}