Gin: Binding JSON having fields with empty string generates validation error

Created on 11 Jul 2016  路  4Comments  路  Source: gin-gonic/gin

I'm honestly not sure whether or not it is the intended behavior or a bug, but here it goes:

type MyRequestStruct struct {
    PropertyOne string `json:"propertyOne" binding:"required"`
    PropertyTwo string `json:"propertyTwo" binding:"required"`
}

func main() {

    engine := gin.New()

    engine.POST("/test", func (ctx *gin.Context) {
        var req MyRequestStruct

        if err := ctx.BindJSON(&req); err != nil {
            ctx.JSON(http.StatusBadRequest, err)
        } else {
            ctx.JSON(http.StatusOK, req)
        }
    })

    engine.Run("localhost:8080")
}

So I have tested with these 3 requests. For me only the last one should fail.

1 -

curl -X POST http://localhost:8080/test -d '{ "propertyOne": "1", "propertyTwo": "2" }' -H "Content-Type: application/json"

Respone:

{
    "propertyOne": "1",
    "propertyTwo": "2"
}

2 -

curl -X POST http://localhost:8080/test -d '{ "propertyOne": "", "propertyTwo": "" }' -H "Content-Type: application/json"

Response:

{
    "MyRequestStruct.PropertyOne": {
        "FieldNamespace": "MyRequestStruct.PropertyOne",
        "NameNamespace": "PropertyOne",
        "Field": "PropertyOne",
        "Name": "PropertyOne",
        "Tag": "required",
        "ActualTag": "required",
        "Kind": 24,
        "Type": {},
        "Param": "",
        "Value": ""
    },
    "MyRequestStruct.PropertyTwo": {
        "FieldNamespace": "MyRequestStruct.PropertyTwo",
        "NameNamespace": "PropertyTwo",
        "Field": "PropertyTwo",
        "Name": "PropertyTwo",
        "Tag": "required",
        "ActualTag": "required",
        "Kind": 24,
        "Type": {},
        "Param": "",
        "Value": ""
    }
}

3 -

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

Returns:

{
    "MyRequestStruct.PropertyOne": {
        "FieldNamespace": "MyRequestStruct.PropertyOne",
        "NameNamespace": "PropertyOne",
        "Field": "PropertyOne",
        "Name": "PropertyOne",
        "Tag": "required",
        "ActualTag": "required",
        "Kind": 24,
        "Type": {},
        "Param": "",
        "Value": ""
    },
    "MyRequestStruct.PropertyTwo": {
        "FieldNamespace": "MyRequestStruct.PropertyTwo",
        "NameNamespace": "PropertyTwo",
        "Field": "PropertyTwo",
        "Name": "PropertyTwo",
        "Tag": "required",
        "ActualTag": "required",
        "Kind": 24,
        "Type": {},
        "Param": "",
        "Value": ""
    }
}

Most helpful comment

that's exactly correct @stxml because of go's static nature it will always have value, think of required as nondefault instead.

but if you really need to check if there is any value you do have options, you can set your strings fields to be pointers to string *string and instead of using required can use the exists tag instead.

All 4 comments

I guess it's intended to work this way. The validation runs on the struct after unmarshalling the request body. It doesn't check the body and can't verify if a value is empty or missing.

that's exactly correct @stxml because of go's static nature it will always have value, think of required as nondefault instead.

but if you really need to check if there is any value you do have options, you can set your strings fields to be pointers to string *string and instead of using required can use the exists tag instead.

@deankarn I encountered the same problem even though I set all parameters with a value and strings fields also set to be pointers.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mdnight picture mdnight  路  3Comments

ghost picture ghost  路  3Comments

lilee picture lilee  路  3Comments

ccaza picture ccaza  路  3Comments

mastrolinux picture mastrolinux  路  3Comments