Echo: Playground Validator doesn't work

Created on 12 Mar 2018  路  3Comments  路  Source: labstack/echo

I follow this documentation -> https://echo.labstack.com/guide/request

My code is:

main.go

package main

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

type CustomValidator struct {
    validator *validator.Validate
}

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

func main() {
    e := echo.New()
    e.Validator = &CustomValidator{validator: validator.New()}

    // TODOS
    e.GET("/todos", getTodos)
    e.POST("/todos", createTodo)

    e.Logger.Fatal(e.Start(":1323"))
}

todo.go

package main

import (
    "github.com/labstack/echo"
)

type Todo struct {
    Title string `json:"title" validate:"required"`
}

var todos = []Todo {
    {
        Title: "Saugen",
    },
}

func getTodos(c echo.Context) error {
    return c.JSONPretty(200, map[string][]Todo {
        "todos": todos,
    }, "    ")
}

func createTodo(c echo.Context) (err error) {
    todo := new(Todo)
    if err = c.Bind(todo); err != nil {
        return
    }
    if err = c.Validate(todo); err != nil {
        return
    }
    todos = append(todos, *todo)
    return c.JSONPretty(200, *todo, "    ")
}

My payload is:

{
    "title": ""
}

My result is:

{
    "message": "Internal Server Error"
}

which should not be!

Console output:

{"time":"2018-03-08T20:51:49.3489642+01:00","level":"ERROR","prefix":"echo","file":"echo.go","line":"286","message":"Key: 'Todo.Title' Error:Field validation for 'Title' failed on the 'required' tag"}

Most helpful comment

Doesn't help...

My solution ist:

func httpError(code int, err error) *echo.HTTPError {
    return echo.NewHTTPError(code, strings.ToLower(err.Error()))
}

func createTodo(c echo.Context) (err error) {
    todo := new(Todo)
    if err = c.Bind(todo); err != nil {
        return
    }
    if e := c.Validate(todo); e != nil {
        err = httpError(400, e)
        return
    }
    return c.JSONPretty(200, *todo, "    ")
}

All 3 comments

That is because you submitted an empty string which is the initial value for strings and therefore the required validator sees this as missing value. You get the same problem if you use required for number types (int, uint16, etc.) and submit 0, or false in case of booleans. If you want to only make sure that the body contains the key, use required but your struct should hold a pointer like *string. An uninitialized string is "" while an uninitialized string pointer is nil and nil != ""

So change to

type Todo struct {
    Title *string `json:"title" validate:"required"`
}

Doesn't help...

My solution ist:

func httpError(code int, err error) *echo.HTTPError {
    return echo.NewHTTPError(code, strings.ToLower(err.Error()))
}

func createTodo(c echo.Context) (err error) {
    todo := new(Todo)
    if err = c.Bind(todo); err != nil {
        return
    }
    if e := c.Validate(todo); e != nil {
        err = httpError(400, e)
        return
    }
    return c.JSONPretty(200, *todo, "    ")
}

I have the same problem,
Does it have any other solution besides a workaround ?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

vishr picture vishr  路  3Comments

syntaqx picture syntaqx  路  3Comments

arun0009 picture arun0009  路  3Comments

spielstein picture spielstein  路  3Comments

montanaflynn picture montanaflynn  路  3Comments