Placing 'required' on a struct doesn't prevent the request from going through. I'm getting some strange behavior with binding in general.

Here is a function:

func CreateTag(c *gin.Context) {
        var ntf NewForm
        c.Bind(&ntf)

        if ntf.Name == "" {
                c.JSON(400, gin.H{"error_message": "tag name required"})
                return
        } 

Presumably if the item is not present in the request, c.Fail should be returning 'Error #01: Required Type' in the response. Yet this does not happen, it passes straight to the conditional (which defeats the whole purpose of validate):

HTTP/1.1 400 Bad Request
Server: nginx
Date: Wed, 10 Sep 2014 00:18:29 GMT
Content-Type: application/json
Content-Length: 38
Connection: keep-alive

{"error_message":"tag name required"}

The error does show up in the gin logs, however:

[GIN] 2014/09/09 - 20:18:29 | 400 |    174.682us | 172.4.231.9 POST /new
Error #01: Required Type 
     Meta: Operation aborted

It also doesn't return correctly for an unknown MIME type:

[GIN] 2014/09/09 - 20:18:53 | 400 |     46.372us | 172.4.231.9 POST /new
Error #01: unknown content-type: pplication/json 
     Meta: Operation aborted

I get the same response from the server, it passes straight through.

Comment From: JimmyPettersson85

Possible duplicate of #100?

Comment From: techjanitor

I'm just using a simple struct here:

type NewForm struct {
        Name string `json:"name" binding:"required"`
        Type int    `json:"type" binding:"required"`
}

Comment From: badoet

hmm i tot its suppose to be

if  !c.Bind(&ntf) {
 // error message
}

the bind will return bool result..

Comment From: techjanitor

That doesn't seem to do anything either ;D

Comment From: badoet

oh another thing, how r u posting the request data. is it in the request body / post form ? post form will not be detected by the c.Bind . u need to manually parse the form data one by one. the bind will only work if the data is in the request body. - things like angularjs automatically perform the correct way

Comment From: techjanitor

It's from AngularJS using ng-resource, json input.

Here is an example:

http://pastebin.com/raw.php?i=QL8ZeHW5

curl -i -H "Content-Type: application/json" -d '{}' ~:5000/post                                                                                                  [22:00:23]
HTTP/1.1 400 Bad Request
Content-Type: application/json
Date: Tue, 23 Sep 2014 03:00:23 GMT
Content-Length: 34

{"error_message":"post required"}

Like I said it's setting the response code correctly and spitting out an error in the logs, so it's clearly working. It just doesn't stop the request?

Comment From: themartorana

@techjanitor it's still up to you to stop the execution of the request with a simple statement, such as

if  !c.Bind(&ntf) {
    c.Fail(...)
    return
}

There's nothing short of a panic that could stop the execution of a handler.

Comment From: techjanitor

Then that should be in the example. What other purpose does Validate serve if it doesn't stop the request? Binding in Martini will stop the request, so I assumed that was the functionality. It seems to be implied:

 If a field is decorated with binding:"required" and has a empty value when binding, the current request will fail with an error.

Comment From: osiloke

I ran into this, and i'm glad i found this post cause i just started using go today and i thought i broke something. Yep, the docs should be updated, and thankfully this is an opensource project, we the community can submit pull requests. It is a bit confusing though, because it is assumed that c.Bind does validation, but it really doesn't. It is used however to marshal the json/form post. You will need some other validation package for that, which i believe the author mentioned as a TODO. This is where i believe gin would start loosing speed and becoming more and more like martini.

Some struct validation, github.com/go-validator/validator

Comment From: techjanitor

That is not correct, please read the OP. Gin binding quite literally has a validate function. I invite you to look at binding.go and read the function.

https://github.com/gin-gonic/gin/blob/develop/binding/binding.go

In addition the documentation says, without any ambiguity, that bind will validate the input and stop the request.

You can also specify that specific fields are required. If a field is decorated with binding:"required" and has a empty value when binding, the current request will fail with an error.

Gin binding features validation. It spits output to the log but fails to stop the function. It is a broken feature.

Comment From: osiloke

Ha, i may have rambled, too much, but i was essentially agreeing with you but suggested that someone around here would probably fix it. I however never took a look at the binding.go code to see the validate function. I've only been on this go thing for a handful of hours, still getting up to speed. Thanks for the note though.

Comment From: davisford

Why was this issue closed? I'm having a similar problem where c.Bind() does not fail with invalid input. The api has also changed so Bind() now returns an error instead of a bool.

It appears that gin uses this validator as it's default, but it does not appear to run for me when I send in JSON with missing tags that are required.

EDIT: now I see, only the binding tag works. I presumed the validate tag would work as it seems to use that other library (noted above). I suppose with some further digging there's a way to plug in the bluesuncorp/validator so those tags are available?

type Foo struct {
   //Name string `validate:"required"` // does not work
  Name string `binding:"required" // does work
}

Comment From: nazwa

This is an old issue and like you said, the binding tags do work. ~~Seems like the docs still need to be updated.~~

Comment From: luongs3

still got trouble with Form Binding

Comment From: SharkFourSix

Bump. Invalid input just crosses path the validator like it's not there when it should fail.