如何检测收到的JSON是否包含未知字段

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.

Update:

you might want to use DisallowUnknownFields() read for more info


old answer:

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?