LoginSignup
3
3

More than 5 years have passed since last update.

フレームワーク「GIN」を使ってみた(バリデーション処理)

Posted at

修正

バリデーション方法

フレームワーク「GIN」を使ってみた(CRUD処理) を改造して、バリデーションを追加します。

今回は、gopkg.in/go-playground/validator.v9 を利用します。

修正内容

以下のソースを追加します。

form/users.go
package forms

import (
    "regexp"

    "gopkg.in/go-playground/validator.v9"
)

type Users struct {
    Id     int
    UserId string `validate:"required,min=5,max=25,alphanum"` // 必須、5~25文字、半角英数
    Name   string `validate:"required,is_tarou"`              // 必須、カスタムバリデーション
}

// tarou はオリジナルバリデーション
func tarou(fl validator.FieldLevel) bool { //引数の型、返り値は固定
    name := fl.Field().String()
    tarou := regexp.MustCompile(`太郎`)
    // name に太郎を含まないとエラーとする
    return tarou.MatchString(name)
}

// バリデーションチェックを行って、結果とNGの場合にエラーメッセージ群を返す
func (form *Users) Validate() (ok bool, result map[string]string) {
    result = make(map[string]string)
    // 構造体のデータをタグで定義した検証方法でチェック
    // err := validator.New().Struct(*form)
    validate := validator.New()
    validate.RegisterValidation("is_tarou", tarou) //第一引数をvalidateタグで設定した名前に合わせる
    err := validate.Struct(*form)
    if err != nil {
        errors := err.(validator.ValidationErrors)
        if len(errors) != 0 {
            for i := range errors {
                // フィールドごとに、検証
                switch errors[i].StructField() {
                case "UserId":
                    switch errors[i].Tag() {
                    case "required", "min", "max", "alphanum":
                        result["UserId"] = "5文字以上25文字以下の半角英数値で入力してください"
                    }
                case "Name":
                    switch errors[i].Tag() {
                    case "required":
                        result["Name"] = "名前を入力してください"
                    case "is_tarou":
                        result["Name"] = "名前には、太郎を利用してください"
                    }
                }
            }
        }
        return false, result
    }
    return true, result
}

上記、バリデーションを登録処理のみ対応します。
修正箇所のみ記載します。

routes/users_controller.go

func Create(c *gin.Context) {
    log.Print("登録処理")
    DbConnection, _ := sql.Open("sqlite3", "./db/sqlite3/test.db") // main.goからのパスを指定
    defer DbConnection.Close()

    userid := c.PostForm("userID")
    name := c.PostForm("name")

    // 処理を追加
    form := forms.Users{
        UserId: userid,
        Name:   name,
    }

    log.Print("UserId : ", form.UserId)
    log.Print("Name : ", form.Name)
    // バリデーションの検証を行う
    if ok, errorMessages := form.Validate(); !ok {
        log.Print("入力エラーあり")
        log.Print(errorMessages)
        // ステータスコード:400を返す。(正しいかは分からない)
        c.HTML(http.StatusBadRequest, "new", gin.H{"User": form, "errorMessages": errorMessages})
        c.Abort()
    }
    // 処理を追加

    cmd := "INSERT INTO m_users (user_id, name) VALUES (?, ?)"
    _, err := DbConnection.Exec(cmd, userid, name)
    if err != nil {
        log.Fatalln(err)
    }
    c.Redirect(http.StatusMovedPermanently, "/user")

}

画面にもエラーメッセージの表示箇所を追加します。

templates/new.html
{{define "new"}}
<!DOCTYPE html>
<html lang="jp">
<head>
    <meta charset="UTF-8">
    <title>新規登録</title>
</head>
<body>
    <form action="/user/new" method="POST">
        user_id:<input type="text" name="userID" value="{{.User.UserId}}"> {{.errorMessages.UserId}}
        <br>
        name: <input type="text" name="name" value="{{.User.Name}}"> {{.errorMessages.Name}}
        <br>
        <input type="submit" value="登録">
  </form>
</body>
</html>
{{end}}

参考サイト

go-playground/validator リクエストパラメータ向けValidationパターンまとめ
golang バリデート(validator.v9)
Golangでバリデーションチェックを行う
公式ドキュメント

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3