10

I'm using Beego framework to build a web application in Go. I have to validate the incoming JSON in an API request.

I can unmarshal the JSON into a struct which works fine, but I want to validate the data as well. For example, if the type doesn't match with the type in struct json.Unmarshal will reutrn an error on the first occurence. I want to validate and get all the errors at once for JSON.

I've tried https://github.com/thedevsaddam/govalidator but the package needs a reference to request object which is not available in the controller of Beego. There are other validators which can validate a struct but i want the json validation as well.

EDIT:

A reference to the request object in beego can be found from the controller's context object as:

func (this *MainController) Post() {
    fmt.Println(this.Ctx.Request)
}

But the problem remains same with json unmarshal. If there's any slight mismatch in the type, json.unmarshal will immediately panic. I want to be able to validate the type as well.

030
  • 10,842
  • 12
  • 78
  • 123
anshuraj
  • 332
  • 1
  • 5
  • 16
  • This isn't supported by the standard library, so it seems you're asking for a 3rd party lib? That is off-topic for SO. – icza May 30 '19 at 12:28
  • Either a 3rd party library or any solution is welcomed. – anshuraj May 30 '19 at 12:29
  • 1
    [`json.Decoder.Token()`](https://golang.org/pkg/encoding/json/#Decoder.Token) might help, but it will require quite a bit of code. – Mihai Todor May 30 '19 at 12:54

4 Answers4

11

Since Golang v1.9 json.Valid([]byte) has been a valid method available from the "encoding/json" package.

Reference: https://golang.org/pkg/encoding/json/#Valid

danielkalen
  • 111
  • 1
  • 2
6

We've used go-playground/validator.v8 for a similar purpose. You can define the data validations with the tags that come out of the box (basic stuff like equality, min/max and even has somthing of an expression lang). On top of that you can add your custom validations. It's all in the docs, hope it helps.

Nestor Sokil
  • 2,162
  • 12
  • 28
1

There is a method checkValid (in encoding/json package) which can do that. This method, however, is not exposed. So, you can use Unmarshal (in same package) to check if JSON is valid.

Aakash Goyal
  • 1,051
  • 4
  • 12
  • 44
1

I had to do this today so I will share my solution. I created a function using unmarshal that returns true or false based on whether the text returns valid json:

// isJSON checks that the string value of the field can unmarshall into valid json
func isJSON(s string) bool {
    var j map[string]interface{}
    if err := json.Unmarshal([]byte(s), &j); err != nil {
        return false
    }
    return true
}

Then I used that logic with the validator package to make and register a custom validation tag that I can use in any struct to validate that a field contains json. You can use go playground to check the full solution and experiment:

// isJSON checks that the string value of the field can unmarshall into valid json
func isJSON(fl validator.FieldLevel) bool {
    var j map[string]interface{}
    if err := json.Unmarshal([]byte(fl.Field().String()), &j); err != nil {
        return false
    }
    return true
}

// register the function with json tag:
validate.RegisterValidation("json", isJSON)
anna
  • 187
  • 1
  • 8