Source file src/encoding/json/v2/doc.go

     1  // Copyright 2020 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build goexperiment.jsonv2
     6  
     7  // Package json implements semantic processing of JSON as specified in RFC 8259.
     8  // JSON is a simple data interchange format that can represent
     9  // primitive data types such as booleans, strings, and numbers,
    10  // in addition to structured data types such as objects and arrays.
    11  //
    12  // See the [Working with JSON] tutorial for an introduction to this package.
    13  //
    14  // [Marshal] and [Unmarshal] encode and decode Go values
    15  // to/from JSON text contained within a []byte.
    16  // [MarshalWrite] and [UnmarshalRead] operate on JSON text
    17  // by writing to or reading from an [io.Writer] or [io.Reader].
    18  // [MarshalEncode] and [UnmarshalDecode] operate on JSON text
    19  // by encoding to or decoding from a [jsontext.Encoder] or [jsontext.Decoder].
    20  // [Options] may be passed to each of the marshal or unmarshal functions
    21  // to configure the semantic behavior of marshaling and unmarshaling
    22  // (i.e., alter how JSON data is understood as Go data and vice versa).
    23  // [jsontext.Options] may also be passed to the marshal or unmarshal functions
    24  // to configure the syntactic behavior of encoding or decoding.
    25  //
    26  // The data types of JSON are mapped to/from the data types of Go based on
    27  // the closest logical equivalent between the two type systems. For example,
    28  // a JSON boolean corresponds with a Go bool,
    29  // a JSON string corresponds with a Go string,
    30  // a JSON number corresponds with a Go int, uint or float,
    31  // a JSON array corresponds with a Go slice or array, and
    32  // a JSON object corresponds with a Go struct or map.
    33  // See the documentation on [Marshal] and [Unmarshal] for a comprehensive list
    34  // of how the JSON and Go type systems correspond.
    35  //
    36  // Arbitrary Go types can customize their JSON representation by implementing
    37  // [Marshaler], [MarshalerTo], [Unmarshaler], or [UnmarshalerFrom].
    38  // This provides authors of Go types with control over how their types are
    39  // serialized as JSON. Alternatively, users can implement functions that match
    40  // [MarshalFunc], [MarshalToFunc], [UnmarshalFunc], or [UnmarshalFromFunc]
    41  // to specify the JSON representation for arbitrary types.
    42  // This provides callers of JSON functionality with control over
    43  // how any arbitrary type is serialized as JSON.
    44  //
    45  // # JSON Representation of Go structs
    46  //
    47  // A Go struct is naturally represented as a JSON object,
    48  // where each Go struct field corresponds with a JSON object member.
    49  // When marshaling, all Go struct fields are recursively encoded in depth-first
    50  // order as JSON object members except those that are ignored or omitted.
    51  // When unmarshaling, JSON object members are recursively decoded
    52  // into the corresponding Go struct fields.
    53  // Object members that do not match any struct fields,
    54  // also known as “unknown members”, are ignored by default or rejected
    55  // if [RejectUnknownMembers] is specified.
    56  //
    57  // The representation of each struct field can be customized in the
    58  // "json" struct field tag, where the tag is a comma-separated list of options.
    59  // As a special case, if the entire tag is `json:"-"`,
    60  // then the field is ignored with regard to its JSON representation.
    61  // Some options also have equivalent behavior controlled by a caller-specified [Options].
    62  // Field-specified options take precedence over caller-specified options.
    63  //
    64  // The first option is the JSON object name override for the Go struct field.
    65  // If the name is not specified, then the Go struct field name
    66  // is used as the JSON object name.
    67  // By default, unmarshaling uses case-sensitive matching to identify
    68  // the Go struct field associated with a JSON object name.
    69  //
    70  // After the name, the following tag options are supported:
    71  //
    72  //   - omitzero: When marshaling, the "omitzero" option specifies that
    73  //     the struct field should be omitted if the field value is zero
    74  //     as determined by the "IsZero() bool" method if present,
    75  //     otherwise based on whether the field is the zero Go value.
    76  //     This option has no effect when unmarshaling.
    77  //
    78  //   - omitempty: When marshaling, the "omitempty" option specifies that
    79  //     the struct field should be omitted if the field value would have been
    80  //     encoded as a JSON null, empty string, empty object, or empty array.
    81  //     This option has no effect when unmarshaling.
    82  //
    83  //   - string: The "string" option specifies that [StringifyNumbers] be set
    84  //     when marshaling or unmarshaling a struct field value.
    85  //     This causes types that would normally be encoded as a JSON number
    86  //     to instead be encoded as a JSON number quoted within a JSON string,
    87  //     and to be decoded from a JSON string containing the JSON number
    88  //     without any surrounding whitespace.
    89  //     The "string" option only applies to the top-level of the Go struct field
    90  //     value. It is an error to apply this option to any type that does not
    91  //     encode as a JSON number.
    92  //     Note that composite types such as arrays, slices, structs, and maps do
    93  //     not encode as a JSON number, so applying this option will cause an error
    94  //     rather than affecting JSON numbers within such types.
    95  //     This extra level of encoding is often necessary since many JSON parsers
    96  //     cannot precisely represent 64-bit integers.
    97  //
    98  //   - case: When unmarshaling, the "case" option specifies how
    99  //     JSON object names are matched with the JSON name for Go struct fields.
   100  //     The option is a key-value pair specified as "case:value" where
   101  //     the value must either be 'ignore' or 'strict'.
   102  //     The 'ignore' value specifies that matching is case-insensitive,
   103  //     and also ignores dashes and underscores. If multiple fields match,
   104  //     then the field with an exact name match is selected, otherwise an error
   105  //     is reported because the choice of field to unmarshal into is ambiguous.
   106  //     The 'strict' value specifies that matching is case-sensitive.
   107  //     This takes precedence over the [MatchCaseInsensitiveNames] option.
   108  //
   109  //   - embed: The "embed" option specifies that
   110  //     the JSON representable content of this field type is to be promoted
   111  //     as if it were specified in the parent struct.
   112  //     It is the JSON equivalent of Go struct embedding.
   113  //     A Go embedded field is implicitly JSON embedded unless
   114  //     an explicit JSON name is specified. The embedded field must be a Go struct
   115  //     (that does not implement any JSON methods), [jsontext.Value],
   116  //     map[~string]T, or an unnamed pointer to such types. When marshaling,
   117  //     embedded fields from a pointer type are omitted if it is nil.
   118  //     Embedded fields of type [jsontext.Value] and map[~string]T are called
   119  //     “embedded fallbacks” as they can represent all possible
   120  //     JSON object members not directly handled by the parent struct.
   121  //     Only one embedded fallback field may be specified in a struct,
   122  //     while many non-fallback fields may be specified. This option
   123  //     must not be specified with any other option (including the JSON name).
   124  //
   125  // The "omitzero" and "omitempty" options behave similarly.
   126  // The former is defined in terms of the Go type system,
   127  // while the latter in terms of the JSON type system.
   128  // Consequently they behave differently in some circumstances.
   129  // For example, only a nil slice or map is omitted under "omitzero", while
   130  // an empty slice or map is omitted under "omitempty" regardless of nilness.
   131  // The "omitzero" option is useful for types with a well-defined zero value
   132  // (e.g., [net/netip.Addr]) or have an IsZero method (e.g., [time.Time.IsZero]).
   133  //
   134  // Every Go struct corresponds to a list of JSON-representable fields
   135  // which is constructed by performing a breadth-first search over
   136  // all struct fields (excluding unexported or ignored fields),
   137  // where the search recursively descends into embedded structs.
   138  // The set of non-embedded fields in a struct must have unique JSON names.
   139  // If multiple fields all have the same JSON name, then the one
   140  // at shallowest depth takes precedence and the other fields at deeper depths
   141  // are excluded from the list of JSON-representable fields.
   142  // If multiple fields at the shallowest depth have the same JSON name,
   143  // but exactly one is explicitly tagged with a JSON name,
   144  // then that field takes precedence and all others are excluded from the list.
   145  // This is analogous to Go visibility rules for struct field selection
   146  // with embedded struct types.
   147  //
   148  // Marshaling or unmarshaling a non-empty struct
   149  // without any JSON-representable fields results in a [SemanticError],
   150  // unless the Go struct has a field with an explicit `json` tag,
   151  // which signals that the type has a valid JSON representation (even if empty).
   152  // Unexported fields must not have any `json` tags except for `json:"-"`.
   153  //
   154  // # Security Considerations
   155  //
   156  // JSON is frequently used as a data interchange format to communicate
   157  // between different systems, possibly implemented in different languages.
   158  // For interoperability and security reasons, it is important that
   159  // all implementations agree upon the semantic meaning of the data.
   160  //
   161  // [For example, suppose we have two micro-services.]
   162  // The first service is responsible for authenticating a JSON request,
   163  // while the second service is responsible for executing the request,
   164  // assuming that it was authenticated.
   165  // If an attacker were able to maliciously craft a JSON request such that
   166  // both services believe that the same request is from different users,
   167  // it could bypass the authenticator with valid credentials for one user,
   168  // but maliciously perform an action on behalf of a different user.
   169  //
   170  // According to RFC 8259, there unfortunately exist many JSON texts
   171  // that are syntactically valid but semantically ambiguous.
   172  // For example, the standard does not define how to interpret duplicate
   173  // names within an object.
   174  //
   175  // The v1 [encoding/json] and [encoding/json/v2] packages
   176  // interpret some inputs in different ways. In particular:
   177  //
   178  //   - The standard specifies that JSON must be encoded using UTF-8.
   179  //     By default, v1 replaces invalid bytes of UTF-8 in JSON strings
   180  //     with the Unicode replacement character,
   181  //     while v2 rejects inputs with invalid UTF-8.
   182  //     To change the default, specify the [jsontext.AllowInvalidUTF8] option.
   183  //     The replacement of invalid UTF-8 is a form of data corruption
   184  //     that alters the precise meaning of strings.
   185  //
   186  //   - The standard does not specify a particular behavior when
   187  //     duplicate names are encountered within a JSON object,
   188  //     which means that different implementations may behave differently.
   189  //     By default, v1 allows for the presence of duplicate names,
   190  //     while v2 rejects duplicate names.
   191  //     To change the default, specify the [jsontext.AllowDuplicateNames] option.
   192  //     If allowed, object members are processed in the order they are observed,
   193  //     meaning that later values will replace or be merged into prior values,
   194  //     depending on the Go value type.
   195  //
   196  //   - The standard defines a JSON object as an unordered collection of name/value pairs.
   197  //     While ordering can be observed through the underlying [jsontext] API,
   198  //     both v1 and v2 generally avoid exposing the ordering.
   199  //     No application should semantically depend on the order of object members.
   200  //     Allowing duplicate names is a vector through which ordering of members
   201  //     can accidentally be observed and depended upon.
   202  //
   203  //   - The standard suggests that JSON object names are typically compared
   204  //     based on equality of the sequence of Unicode code points,
   205  //     which implies that comparing names is often case-sensitive.
   206  //     When unmarshaling a JSON object into a Go struct,
   207  //     by default, v1 uses a (loose) case-insensitive match on the name,
   208  //     while v2 uses a (strict) case-sensitive match on the name.
   209  //     To change the default, specify the [MatchCaseInsensitiveNames] option.
   210  //     The use of case-insensitive matching provides another vector through
   211  //     which duplicate names can occur. Allowing case-insensitive matching
   212  //     means that v1 or v2 might interpret JSON objects differently from most
   213  //     other JSON implementations (which typically use a case-sensitive match).
   214  //
   215  //   - The standard does not specify a particular behavior when
   216  //     an unknown name in a JSON object is encountered.
   217  //     When unmarshaling a JSON object into a Go struct, by default
   218  //     both v1 and v2 ignore unknown names and their corresponding values.
   219  //     To change the default, specify the [RejectUnknownMembers] option.
   220  //
   221  //   - The standard suggests that implementations may use a float64
   222  //     to represent a JSON number. Consequently, large JSON integers
   223  //     may lose precision when stored as a floating-point type.
   224  //     Both v1 and v2 correctly preserve precision when marshaling and
   225  //     unmarshaling a concrete integer type. However, even if v1 and v2
   226  //     preserve precision for concrete types, other JSON implementations
   227  //     may not be able to preserve precision for outputs produced by v1 or v2.
   228  //     The `string` tag option can be used to specify that an integer type
   229  //     is to be quoted within a JSON string to avoid loss of precision.
   230  //     Furthermore, v1 and v2 may still lose precision when unmarshaling
   231  //     into an any interface value, where unmarshal uses a float64
   232  //     by default to represent a JSON number.
   233  //     To change the default, specify the [WithUnmarshalers] option
   234  //     with a custom unmarshaler that pre-populates the interface value
   235  //     with a concrete Go type that can preserve precision.
   236  //
   237  // RFC 8785 specifies a canonical form for any JSON text,
   238  // which explicitly defines specific behaviors that RFC 8259 leaves undefined.
   239  // In theory, if a text can successfully [jsontext.Value.Canonicalize]
   240  // without changing the semantic meaning of the data, then it provides a
   241  // greater degree of confidence that the data is more secure and interoperable.
   242  //
   243  // The v2 API generally chooses more secure defaults than v1,
   244  // but care should still be taken with large integers or unknown members.
   245  //
   246  // [Working with JSON]: https://go.dev/doc/tutorial/json
   247  // [For example, suppose we have two micro-services.]: https://www.youtube.com/watch?v=avilmOcHKHE&t=1057s
   248  package json
   249  
   250  // requireKeyedLiterals can be embedded in a struct to require keyed literals.
   251  type requireKeyedLiterals struct{}
   252  
   253  // nonComparable can be embedded in a struct to prevent comparability.
   254  type nonComparable [0]func()
   255  

View as plain text