-
Notifications
You must be signed in to change notification settings - Fork 628
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Values of the Decimal type get marshaled to JSON as strings, not numbers #21
Comments
I followed Python's practices on this matter. Python's simplejson package serializes decimal.Decimals as strings, so this is why I chose to do so as well. If I had to guess a reason for it, I would say that it's safer: there is no chance someone on the other end of the wire could use the default behavior of most JSON deserializers and deserialize the decimal into a float, thus losing precision or introducing rounding errors. |
Fair enough, thanks. I think in my case I'll go with some workaround--custom type for
Since I'm using your package for working with money, I'm not afraid of |
Please open a branch or configure it in some way so that values of decimal type can be grouped into JSON as numbers instead of strings, which is not friendly to cross language interaction |
For the next person who comes along with a "shopspring decimal as number in JSON" search, this behaviour is now configurable:
|
But seems like one needs more precise control over it - maybe one should need configurability for this via JSON tag options e.g? Because the global state is evil as all we know. |
I agree with the comment above, having a non global way of setting this configuration would be preferable. We encounter an issue where a dependency of a dependency has changed that value and broke a service that was expecting the decimal to be encoded as a string See the comment below as reference: dolthub/go-mysql-server@b1d1581#commitcomment-142143687 By the way Thank you for implementing this library, has been very useful! |
@nicktobey (from go-mysql-server) has brought to my attention that there is a possible solution being discussed in #206 |
This line wraps the string representation of a value into double quotes which get transferred "as is" into the resulting JSON representation.
While I understand that a package is free to pick any "on-the-wire" representation for the values of the types it works with, I would make a claim that the selected approach is incorrect: the JSON spec defines the representation for "numbers" -- which includes both "plain" integers and floating-point values in the scientific notation, and the
Decimal
type provided by this package represents numbers, so I would expect it to serialize into JSON as numbers as well.The rationale is that a receiving end for JSON representations serialized from
Decimal
values handled by this package is not necessarily written using the same package (or even in Go), so it naturally expects to parse these representations to whatever numeric type it supports -- be it floats, Java'sBigDecimal
, .NET'sdecimal
and so on. Currently we either rely on some sloppiness of the receiver's decoder (for instance, the Json.Net library is happy to parse whatever this package produces intodecimal
s) or require custom unmarshaling.Actually the inconsistency I'm talking about was caught by the testing code in one of my packages -- which tested JSON serialization of whatever stuff my package generates -- after I converted its parts which work with amounts of money to use
Decimal
rather than stockfloat64
: floats were marshaled as numbers, andDecimal
s suddenly got double-quoted (while containing the same string representations as floats).TL;DR
I think that
Decimal
s should be marshaled to JSON as numbers, not as strings.The text was updated successfully, but these errors were encountered: