Source File
doc.go
Belonging Package
encoding/json/v2
// Copyright 2020 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.//go:build goexperiment.jsonv2// Package json implements semantic processing of JSON as specified in RFC 8259.// JSON is a simple data interchange format that can represent// primitive data types such as booleans, strings, and numbers,// in addition to structured data types such as objects and arrays.//// See the [Working with JSON] tutorial for an introduction to this package.//// [Marshal] and [Unmarshal] encode and decode Go values// to/from JSON text contained within a []byte.// [MarshalWrite] and [UnmarshalRead] operate on JSON text// by writing to or reading from an [io.Writer] or [io.Reader].// [MarshalEncode] and [UnmarshalDecode] operate on JSON text// by encoding to or decoding from a [jsontext.Encoder] or [jsontext.Decoder].// [Options] may be passed to each of the marshal or unmarshal functions// to configure the semantic behavior of marshaling and unmarshaling// (i.e., alter how JSON data is understood as Go data and vice versa).// [jsontext.Options] may also be passed to the marshal or unmarshal functions// to configure the syntactic behavior of encoding or decoding.//// The data types of JSON are mapped to/from the data types of Go based on// the closest logical equivalent between the two type systems. For example,// a JSON boolean corresponds with a Go bool,// a JSON string corresponds with a Go string,// a JSON number corresponds with a Go int, uint or float,// a JSON array corresponds with a Go slice or array, and// a JSON object corresponds with a Go struct or map.// See the documentation on [Marshal] and [Unmarshal] for a comprehensive list// of how the JSON and Go type systems correspond.//// Arbitrary Go types can customize their JSON representation by implementing// [Marshaler], [MarshalerTo], [Unmarshaler], or [UnmarshalerFrom].// This provides authors of Go types with control over how their types are// serialized as JSON. Alternatively, users can implement functions that match// [MarshalFunc], [MarshalToFunc], [UnmarshalFunc], or [UnmarshalFromFunc]// to specify the JSON representation for arbitrary types.// This provides callers of JSON functionality with control over// how any arbitrary type is serialized as JSON.//// # JSON Representation of Go structs//// A Go struct is naturally represented as a JSON object,// where each Go struct field corresponds with a JSON object member.// When marshaling, all Go struct fields are recursively encoded in depth-first// order as JSON object members except those that are ignored or omitted.// When unmarshaling, JSON object members are recursively decoded// into the corresponding Go struct fields.// Object members that do not match any struct fields,// also known as “unknown members”, are ignored by default or rejected// if [RejectUnknownMembers] is specified.//// The representation of each struct field can be customized in the// "json" struct field tag, where the tag is a comma-separated list of options.// As a special case, if the entire tag is `json:"-"`,// then the field is ignored with regard to its JSON representation.// Some options also have equivalent behavior controlled by a caller-specified [Options].// Field-specified options take precedence over caller-specified options.//// The first option is the JSON object name override for the Go struct field.// If the name is not specified, then the Go struct field name// is used as the JSON object name.// By default, unmarshaling uses case-sensitive matching to identify// the Go struct field associated with a JSON object name.//// After the name, the following tag options are supported://// - omitzero: When marshaling, the "omitzero" option specifies that// the struct field should be omitted if the field value is zero// as determined by the "IsZero() bool" method if present,// otherwise based on whether the field is the zero Go value.// This option has no effect when unmarshaling.//// - omitempty: When marshaling, the "omitempty" option specifies that// the struct field should be omitted if the field value would have been// encoded as a JSON null, empty string, empty object, or empty array.// This option has no effect when unmarshaling.//// - string: The "string" option specifies that [StringifyNumbers] be set// when marshaling or unmarshaling a struct field value.// This causes types that would normally be encoded as a JSON number// to instead be encoded as a JSON number quoted within a JSON string,// and to be decoded from a JSON string containing the JSON number// without any surrounding whitespace.// The "string" option only applies to the top-level of the Go struct field// value. It is an error to apply this option to any type that does not// encode as a JSON number.// Note that composite types such as arrays, slices, structs, and maps do// not encode as a JSON number, so applying this option will cause an error// rather than affecting JSON numbers within such types.// This extra level of encoding is often necessary since many JSON parsers// cannot precisely represent 64-bit integers.//// - case: When unmarshaling, the "case" option specifies how// JSON object names are matched with the JSON name for Go struct fields.// The option is a key-value pair specified as "case:value" where// the value must either be 'ignore' or 'strict'.// The 'ignore' value specifies that matching is case-insensitive,// and also ignores dashes and underscores. If multiple fields match,// then the field with an exact name match is selected, otherwise an error// is reported because the choice of field to unmarshal into is ambiguous.// The 'strict' value specifies that matching is case-sensitive.// This takes precedence over the [MatchCaseInsensitiveNames] option.//// - embed: The "embed" option specifies that// the JSON representable content of this field type is to be promoted// as if it were specified in the parent struct.// It is the JSON equivalent of Go struct embedding.// A Go embedded field is implicitly JSON embedded unless// an explicit JSON name is specified. The embedded field must be a Go struct// (that does not implement any JSON methods), [jsontext.Value],// map[~string]T, or an unnamed pointer to such types. When marshaling,// embedded fields from a pointer type are omitted if it is nil.// Embedded fields of type [jsontext.Value] and map[~string]T are called// “embedded fallbacks” as they can represent all possible// JSON object members not directly handled by the parent struct.// Only one embedded fallback field may be specified in a struct,// while many non-fallback fields may be specified. This option// must not be specified with any other option (including the JSON name).//// The "omitzero" and "omitempty" options behave similarly.// The former is defined in terms of the Go type system,// while the latter in terms of the JSON type system.// Consequently they behave differently in some circumstances.// For example, only a nil slice or map is omitted under "omitzero", while// an empty slice or map is omitted under "omitempty" regardless of nilness.// The "omitzero" option is useful for types with a well-defined zero value// (e.g., [net/netip.Addr]) or have an IsZero method (e.g., [time.Time.IsZero]).//// Every Go struct corresponds to a list of JSON-representable fields// which is constructed by performing a breadth-first search over// all struct fields (excluding unexported or ignored fields),// where the search recursively descends into embedded structs.// The set of non-embedded fields in a struct must have unique JSON names.// If multiple fields all have the same JSON name, then the one// at shallowest depth takes precedence and the other fields at deeper depths// are excluded from the list of JSON-representable fields.// If multiple fields at the shallowest depth have the same JSON name,// but exactly one is explicitly tagged with a JSON name,// then that field takes precedence and all others are excluded from the list.// This is analogous to Go visibility rules for struct field selection// with embedded struct types.//// Marshaling or unmarshaling a non-empty struct// without any JSON-representable fields results in a [SemanticError],// unless the Go struct has a field with an explicit `json` tag,// which signals that the type has a valid JSON representation (even if empty).// Unexported fields must not have any `json` tags except for `json:"-"`.//// # Security Considerations//// JSON is frequently used as a data interchange format to communicate// between different systems, possibly implemented in different languages.// For interoperability and security reasons, it is important that// all implementations agree upon the semantic meaning of the data.//// [For example, suppose we have two micro-services.]// The first service is responsible for authenticating a JSON request,// while the second service is responsible for executing the request,// assuming that it was authenticated.// If an attacker were able to maliciously craft a JSON request such that// both services believe that the same request is from different users,// it could bypass the authenticator with valid credentials for one user,// but maliciously perform an action on behalf of a different user.//// According to RFC 8259, there unfortunately exist many JSON texts// that are syntactically valid but semantically ambiguous.// For example, the standard does not define how to interpret duplicate// names within an object.//// The v1 [encoding/json] and [encoding/json/v2] packages// interpret some inputs in different ways. In particular://// - The standard specifies that JSON must be encoded using UTF-8.// By default, v1 replaces invalid bytes of UTF-8 in JSON strings// with the Unicode replacement character,// while v2 rejects inputs with invalid UTF-8.// To change the default, specify the [jsontext.AllowInvalidUTF8] option.// The replacement of invalid UTF-8 is a form of data corruption// that alters the precise meaning of strings.//// - The standard does not specify a particular behavior when// duplicate names are encountered within a JSON object,// which means that different implementations may behave differently.// By default, v1 allows for the presence of duplicate names,// while v2 rejects duplicate names.// To change the default, specify the [jsontext.AllowDuplicateNames] option.// If allowed, object members are processed in the order they are observed,// meaning that later values will replace or be merged into prior values,// depending on the Go value type.//// - The standard defines a JSON object as an unordered collection of name/value pairs.// While ordering can be observed through the underlying [jsontext] API,// both v1 and v2 generally avoid exposing the ordering.// No application should semantically depend on the order of object members.// Allowing duplicate names is a vector through which ordering of members// can accidentally be observed and depended upon.//// - The standard suggests that JSON object names are typically compared// based on equality of the sequence of Unicode code points,// which implies that comparing names is often case-sensitive.// When unmarshaling a JSON object into a Go struct,// by default, v1 uses a (loose) case-insensitive match on the name,// while v2 uses a (strict) case-sensitive match on the name.// To change the default, specify the [MatchCaseInsensitiveNames] option.// The use of case-insensitive matching provides another vector through// which duplicate names can occur. Allowing case-insensitive matching// means that v1 or v2 might interpret JSON objects differently from most// other JSON implementations (which typically use a case-sensitive match).//// - The standard does not specify a particular behavior when// an unknown name in a JSON object is encountered.// When unmarshaling a JSON object into a Go struct, by default// both v1 and v2 ignore unknown names and their corresponding values.// To change the default, specify the [RejectUnknownMembers] option.//// - The standard suggests that implementations may use a float64// to represent a JSON number. Consequently, large JSON integers// may lose precision when stored as a floating-point type.// Both v1 and v2 correctly preserve precision when marshaling and// unmarshaling a concrete integer type. However, even if v1 and v2// preserve precision for concrete types, other JSON implementations// may not be able to preserve precision for outputs produced by v1 or v2.// The `string` tag option can be used to specify that an integer type// is to be quoted within a JSON string to avoid loss of precision.// Furthermore, v1 and v2 may still lose precision when unmarshaling// into an any interface value, where unmarshal uses a float64// by default to represent a JSON number.// To change the default, specify the [WithUnmarshalers] option// with a custom unmarshaler that pre-populates the interface value// with a concrete Go type that can preserve precision.//// RFC 8785 specifies a canonical form for any JSON text,// which explicitly defines specific behaviors that RFC 8259 leaves undefined.// In theory, if a text can successfully [jsontext.Value.Canonicalize]// without changing the semantic meaning of the data, then it provides a// greater degree of confidence that the data is more secure and interoperable.//// The v2 API generally chooses more secure defaults than v1,// but care should still be taken with large integers or unknown members.//// [Working with JSON]: https://go.dev/doc/tutorial/json// [For example, suppose we have two micro-services.]: https://www.youtube.com/watch?v=avilmOcHKHE&t=1057spackage json// requireKeyedLiterals can be embedded in a struct to require keyed literals.type requireKeyedLiterals struct{}// nonComparable can be embedded in a struct to prevent comparability.type nonComparable [0]func()
The pages are generated with Golds v0.8.4. (GOOS=linux GOARCH=amd64)