I'm trying to find some way to prohibit arbitrary JSON keys and fields in Go. For now, if I send payload with undeclared fields in struct, the service will work normally and will map the entity described fields (likejson:"id,omitempty"
). For example:
type Foo struct {
Bar int `json:"id,omitempty"`
}
Received JSON:
{
"id": 12,
"hey": "hey"
}
Can anybody help me to find the way of tracking unknown field in payload? I need to return an error in that case.
you might want to use DisallowUnknownFields()
read for more info
There is a proposal for golang 1.9 on this: proposal: some way to reject unknown fields in encoding/json.Decoder
Till then you could try something like this playground (code also below). The key idea is to parse the json into a map[string]interface{} and then work with the keys. This will of course get much more complicated if you have nested structs.
package main
import (
"encoding/json"
"fmt"
)
type Foo struct {
Bar int `json:"id,omitempty"`
}
var allowedFooKeys = []string{"id"}
func main() {
b := []byte(`{
"id": 12,
"hey": "hey"
}`)
m := map[string]interface{}{}
if err := json.Unmarshal(b, &m); err != nil {
panic(err)
}
for k, _ := range m {
if !keyExists(k, allowedFooKeys) {
fmt.Println("Disallowed key in JSON:", k)
}
}
}
func keyExists(key string, keys []string) bool {
for _, k := range keys {
if k == key {
return true
}
}
return false
}
You can even get rid of the variable allowedFooKeys
by getting the allowed keys directly from the Foo
struct using reflect. For more info on that see here: How to read struct field ` ` decorators?