-
Notifications
You must be signed in to change notification settings - Fork 108
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
Strictly decode to case class disallowing extraneous fields in JSON #104
Comments
@LeifW You can use validate to do that: https://github.com/argonaut-io/argonaut/blob/master/src/main/scala/argonaut/DecodeJson.scala#L55-L65 |
I will leave this open, as a reminder to add an example in the docs. Let me know if this doesn't address what you need. From your example:
Also let me know if there is a general formulation that would let you not specify the validation function explicitly. It is worth noting that it used to be the default, but it was changed because some found it not desirable - but also because it generated fairly poor error messages - if we could address the poor errors part, I would be happy to add some more combinators to make it easy to validate without specifying a custom error message. |
@markhibberd The URL you pasted is dead. Do you have any examples on how to use |
To make sure that I understand this problem, @LeifW, let's please consider an example. Given:
you would expect, either by default in |
Exactly, yes, thanks for the example. I guess I'd lean towards the optional
decodeExactly; I think people are used to the present behavior. A use case
I was thinking of was better error messages. For large complex structures
it can be easy to misspell a field, and the "missing field foo" would be
easier to figure out when accompanied by a "unexpected field foob". Also
sometimes people pass extra fields in their JSON API calls, and then they
just get cargo culted in successive generations, even though they never did
anything - people are afraid to remove them for fear of breaking something.
I'd like to head that kind of thing off explicitly at the beginning.
…On Apr 2, 2017 10:35 AM, "Kevin Meredith" ***@***.***> wrote:
To make sure that I understand this problem, @LeifW
<https://github.com/LeifW>, let's consider an example.
Given:
import argonaut._, Argonaut._
case class Person(name: String)
implicit def decode: DecodeJson[Person] =
DecodeJson ( c =>
for {
name <- (c --\ "name").as[String]
} yield Person(name)
)
scala> Parse.decode[Person]("""{"name": "Bob", "foo": "dunno"}""")
res5: Either[Either[String,(String, argonaut.CursorHistory)],Person] = Right(Person(Bob))
you would expect, either by default in Parse#decode or an optional
Parse#decodeExactly, that the extra foo field should result in a Left
rather than Right?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#104 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AABwJyntLvpVufcOEZ05MRnMO0f0xLsrks5rr9xIgaJpZM4B8veS>
.
|
|
Thanks, @seanparsons, for pointing me to that method! Locally, I added the following:
to this line. Then, I re-ran the above example via JSON contains exact # of fields, one, as case class to which it's decoded
JSON has one extra field, i.e. not in the Person
After decoding, i.e. I looked at the scaladocs for |
@kevinmeredith Not walked? I think you'd be better off just checking that |
Could you please say more? Taking your reply, @seanparsons, I posted this StackOverflow question - http://stackoverflow.com/questions/43433054/retrieving-traversed-json-fields. I appreciate any help, please. |
@kevinmeredith This is what you want to check against correct?
|
@seanparsons Given: case class Person(name: String) and:
How would you use Also, my original thought was add an
Thanks for your continued help. |
Well surely the Unless I'm mistaken that means in the To support a |
Given all of the fields of a https://stackoverflow.com/a/27445097/409976 shows how, using With respect to the second problem, i.e. getting all keys from a
Does a Finally, if you all find this approach to be technically sound, then perhaps it belongs in https://github.com/alexarchambault/argonaut-shapeless? |
@kevinmeredith The Hence this: scala> val testDecoder: DecodeJson[(String, Boolean)] = jdecode2L((a: String, b: Boolean) => (a, b))("a", "b")
testDecoder: argonaut.DecodeJson[(String, Boolean)] = argonaut.DecodeJson$$anon$4@3f59fa4e
scala> val improvedTestDecoder = testDecoder.validate(_.fieldSet == Some(Set("a", "b")), "Wrong fields")
improvedTestDecoder: argonaut.DecodeJson[(String, Boolean)] = argonaut.DecodeJson$$anon$4@45ed447c
scala> improvedTestDecoder.decodeJson(Json("a" := "q", "b" := true))
res7: argonaut.DecodeResult[(String, Boolean)] = DecodeResult(Right((q,true)))
scala> improvedTestDecoder.decodeJson(Json("a" := "q", "b" := true, "c" := 1))
res8: argonaut.DecodeResult[(String, Boolean)] = DecodeResult(Left((Wrong fields,CursorHistory(List())))) |
As I understand your reply, @seanparsons, you believe the If so, perhaps I should ask if the application of |
@kevinmeredith I was pointing out the manual solution, a generic solution would likely want to invoke the same kind of code. It would definitely be a nice thing to have in |
That's definitely do-able with argonaut-shapeless. It has some |
So that
will yield something about "Error: unexpected field "foo"".
Is this feasible?
Example use case: When people call our API, it would be helpful to tell them if the misspelled a key or added junk that doesn't do anything - tell them that's not key that means anything to us and it'll be ignored / rejected as invalid.
The text was updated successfully, but these errors were encountered: