-
-
Notifications
You must be signed in to change notification settings - Fork 134
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
Double values with 0 fraction written without fraction #107
Comments
This sounds more like a feature request than a bug, and I don't know if your use case is the right approach. JSON itself does not distinguish between integers and real numbers. There is only one number type. It is common for JSON implementations to normalize the representation of numbers. I can see the value of pretty-printing JSON for presentational purposes, and I think it'd be reasonable for play-json to make that configurable, but I don't think it's something you should rely on. |
KairosDB (time series database) wants to see json values with RFC 7159 does not mention anything about normalization. I have a hard time to believe this would be common unless in the language itself you can not make a difference (js). I see no reason why play-json could not keep the precision and represent the numbers as printed by BigDecimal or with at least one fractional digit if the source of the number was a double. This will not break anything for existing users. The only reason that comes to mind would be a (marginal) reduction of bandwidth which the user could mitigate by replacing doubles without fraction by integers scala> val x = BigDecimal(1d)
x: scala.math.BigDecimal = 1.0
scala> val x = BigDecimal(1)
x: scala.math.BigDecimal = 1
scala> val x = BigDecimal(1.00d)
x: scala.math.BigDecimal = 1.0
scala> val x = BigDecimal("1.00")
x: scala.math.BigDecimal = 1.00 |
Even if Jackson has a different default behaviour, the Play one is not invalid. Issue with changing it in Play for specific use case as the one with KairoDB is prone to break the compatibility. I would rather suggest to try to customize |
I agree that the current behaviour is not invalid as the spec has no specifics on the subject. Feel free to close this, we can always write our own stringify. |
My understanding has always been that a JSON number is a representation of a number, and was intended to be interpreted as only a number by the recipient of the JSON. For example Wikipedia says:
I don't know much about KairosDB specifically but it seems like a sloppy choice to choose JSON when the spec does not explicitly distinguish between different representations of numbers.
You're right, it doesn't. That's why I said this could be a configurable option, e.g. to print the
It won't break anything for users who don't already expect some particular rendering of numbers, but it would probably annoy users who expect the current rendering and rely on it in some respect. Now that we've introduced a configuration mechanism for play-json I think we should explore how to resolve it that way. I would not be opposed to switching the default behavior to printing the string value of the BigDecimal as long as there's a way to configure it back. |
Rather keep the default behaviour and also to configure it in other way. |
One more remark, on the reading side play-json supports making the difference between val json = Json.parse("""{"test": 1.0}""")
println((json \ "test").as[BigDecimal])
val json2 = Json.parse("""{"test": 1}""")
println((json2 \ "test").as[BigDecimal]) output
|
Another use case for this is with ElasticSearch's dynamic mapping feature. That will map 1.0 as a double field, but 1 as a long field. Doing custom serialization in our code base isn't ideal, so I went ahead and created a PR for this. The new behavior is opt-in using a system property. |
play-json 2.6.5
issue
Play json will serialize
JsNumber(BigDecimal("1.0"))
to1
where this should be1.0
reproducer
output looks like this
The code explicitly strips trailing zeros, this is a loss of precision:
https://github.com/playframework/play-json/blob/master/play-json/jvm/src/main/scala/play/api/libs/json/jackson/JacksonJson.scala#L66
usecase
Writing to KairosDB will create a schema for Real values if the incoming datapoint contains a
.
, otherwise data is seen as Integer.The text was updated successfully, but these errors were encountered: