At the moment we can unmarshal primitives from explicit types and strings if we use json:",string" for the value. My proposal is somewhat the oposit. I want to be able to create a string from any primitives. Only primitives should apply, object and array types should return json.UnmarshalTypeError.
Example
{"val":{}} // json.UnmarshalTypeError
{"val":[]} // json.UnmarshalTypeError
{"val":null} // val: "null" as string
{"val":true} // val: "true" as string
{"val":false} // val: "false" as string
{"val":42} // val: "42" as string
{"val":4.2} // val: "4.2" as string
{"val":"42"} // val: "42" as string
{"val":"asd\"a"} // val: `asd"a` as string
json:",string" on a string type tells that all primitives should be converted to a string.
typesstruct {
Valstring`json:"val,string"`
}
Why do you want this?
I have an endpoint where one of the field supposed to be a string. However, some clients uses dynamically typed languages to create the JSON and this causes an issue where the field which supposed to be a string becomes a number instead. At the moment a custom string type is used which implements json.Unmarshaler.
The text was updated successfully, but these errors were encountered:
ianlancetaylor
changed the title
propsal: json/encode: ability to unmarshal primitives as string
proposal: json/encode: ability to unmarshal primitives as string
Apr 18, 2020
ianlancetaylor
changed the title
proposal: json/encode: ability to unmarshal primitives as string
proposal: encoding/json: ability to unmarshal primitives as string
Apr 18, 2020
It seems like there is a way to do this, and it's not going to be a common request. We generally resist adding new knobs to complex packages like encoding/json, because every new knob makes the package harder to use, harder to test, and harder to fix. Is there a compelling reason for us to add this to the package? Thanks.
The documentation for json.Marshal says the following:
The "string" option signals that a field is stored as JSON inside a
JSON-encoded string. It applies only to fields of string, floating point,
integer, or boolean types. This extra level of encoding is sometimes used
when communicating with JavaScript programs:
Int64String int64 `json:",string"`
With the use of `json:",string"` we can force a primitive type to be encoded as string. There was already an option to do this by implementing json.Marshaler. If there is an option to encode primitives as a string without implementing json.Marshaler wouldn't it make sense to decode primitives as a string without implementing json.Unmarshaler? This could be useful "when communicating with JavaScript programs" since JavaScript is dynamically typed and cannot guarantee the type.
I do not have any other compelling reason. Feel free to close this issue if you disagree. As you mentioned encoding/json is already complex and I can understand if it doesn't need any additional complexity.
I share @ianlancetaylor's thoughts. The options should only cover common use cases, and this seems niche enough that writing twenty lines of extra code seems fine. The code you shared above also seems pretty clean, to be honest. You can also make it behave any way you want, without having to worry about adding complex options to encoding/json.
Really, this is exactly why the marshaler/unmarshaler interfaces were designed. They might be a bit cumbersome to use, but they are really powerful when it comes to custom encoding/decoding behavior.
What version of Go are you using (
go version
)?What do you want?
At the moment we can unmarshal primitives from explicit types and strings if we use
json:",string"
for the value. My proposal is somewhat the oposit. I want to be able to create astring
from any primitives. Only primitives should apply, object and array types should returnjson.UnmarshalTypeError
.Example
Option 1 (preferred by me)
Explicit list of the acceptable types (and
null
).Option 2
json:",string"
on astring
type tells that all primitives should be converted to astring
.Why do you want this?
I have an endpoint where one of the field supposed to be a
string
. However, some clients uses dynamically typed languages to create the JSON and this causes an issue where the field which supposed to be astring
becomes anumber
instead. At the moment a customstring
type is used which implementsjson.Unmarshaler
.Example
The text was updated successfully, but these errors were encountered: