Strict JSON decoding with unknown fields
Go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"strings"
)
// DecodeStrict decodes exactly one JSON value and rejects unknown fields
// and trailing data, which is useful when validating request payloads.
func DecodeStrict(data []byte, target any) error {
decoder := json.NewDecoder(bytes.NewReader(data))
decoder.DisallowUnknownFields()
if err := decoder.Decode(target); err != nil {
return fmt.Errorf("decode: %w", err)
}
if err := decoder.Decode(new(json.RawMessage)); err != io.EOF {
if err == nil {
return fmt.Errorf("decode: unexpected trailing data")
}
return fmt.Errorf("decode: trailing data: %w", err)
}
return nil
}
func main() {
var payload struct {
Name string `json:"name"`
Age int `json:"age"`
}
fmt.Println(DecodeStrict([]byte(`{"name":"Ada","age":36}`), &payload))
err := DecodeStrict([]byte(`{"name":"Ada","age":36,"admin":true}`), &payload)
fmt.Println(strings.Contains(err.Error(), "unknown field"))
}