Encoding
encoding/json: 未知フィールドは既定で無視される
json.Unmarshalはstructに存在しないキーを既定で無視し、DecoderのDisallowUnknownFieldsで拒否できます。
Sourceunknown_fields.go
Go 1.22
package encodingexample
import (
"encoding/json"
"strings"
)
type CreateUserInput struct {
Name string `json:"name"`
}
func DecodeIgnoringUnknown(input string) (CreateUserInput, error) {
var user CreateUserInput
err := json.Unmarshal([]byte(input), &user)
return user, err
}
func DecodeRejectingUnknown(input string) (CreateUserInput, error) {
var user CreateUserInput
decoder := json.NewDecoder(strings.NewReader(input))
decoder.DisallowUnknownFields()
err := decoder.Decode(&user)
return user, err
}Testunknown_fields_test.go
Go 1.22
package encodingexample
import "testing"
func TestEncodingJsonは未知フィールドを既定で無視しDisallowUnknownFieldsで拒否できる(t *testing.T) {
const input = `{"name":"gopher","role":"admin"}`
ignored, err := DecodeIgnoringUnknown(input)
if err != nil {
t.Fatalf("DecodeIgnoringUnknown() error = %v", err)
}
if ignored.Name != "gopher" {
t.Fatalf("DecodeIgnoringUnknown().Name = %q, want %q", ignored.Name, "gopher")
}
if _, err := DecodeRejectingUnknown(input); err == nil {
t.Fatal("DecodeRejectingUnknown() error = nil, want unknown-field error")
}
}01Assertion
このテストで確認できること
- nameと未知のroleを持つJSONをstructへデコードする
- 既定のUnmarshalはroleを無視し、厳格なDecoderはエラーを返す
外部入力のスペルミスを検出したい管理APIなどでは、Decoder.DisallowUnknownFieldsを使う判断があります。一方で前方互換性が必要な公開APIでは、未知フィールドを受け入れる契約が適切な場合もあります。
OBSERVED RESULT
json.Unmarshal → Name: gopher, error: nil
DisallowUnknownFields → error: unknown field "role"