Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 08:20
    codecov[bot] commented #1674
  • 08:19
    codecov[bot] commented #1683
  • 08:19
    codecov[bot] commented #1674
  • 08:18
    codecov[bot] commented #1674
  • 08:18
    codecov[bot] commented #1674
  • 08:10
    codecov[bot] commented #1683
  • 08:09
    codecov[bot] commented #1683
  • 08:09
    codecov[bot] commented #1683
  • 08:08

    blast-hardcheese on master

    Update jackson-annotations, jac… Merge pull request #1677 from s… (compare)

  • 08:08
    blast-hardcheese closed #1677
  • 08:08
    codecov[bot] commented #1683
  • 08:08
    codecov[bot] commented #1683
  • 08:08

    blast-hardcheese on master

    Update jackson-datatype-jsr310 … Merge pull request #1678 from s… (compare)

  • 08:08
    blast-hardcheese closed #1678
  • 08:08
    codecov[bot] commented #1683
  • 08:07

    blast-hardcheese on master

    Update jackson-module-scala to … Merge pull request #1679 from s… (compare)

  • 08:07
    blast-hardcheese closed #1679
  • 08:07
    codecov[bot] commented #1683
  • 08:06
    codecov[bot] commented #1683
  • 08:06
    codecov[bot] commented #1683
blast_hardcheese
@blast_hardcheese:matrix.org
[m]
kk
kelnos
@kelnos:matrix.org
[m]
thinking more about the defaults thing in clients vs. servers, i think it's actually kinda sorta vaguely ok to not care about the difference. because:
1) on the server side, if there are response fields with a default, the server should always send those defaults rather than sending missing values, so the client's default-fallback machinery won't ever trigger.
2) on the client side, if there are request fields with a default, they'll be documented as such in the docs for the version of the client that the user is using, so they should be like "ok, i'm satisfied with default X, so i don't need to pass a different value". if the default value on the server side changes, sure, the "old" default will still get passed by old clients, but presumably the people using those clients know that and are ok with it.
3) on a somewhat higher level, if customers are using guardrail-generated clients and servers, defaults will never come into play on deserialization anyway, because guardrail-generated clients will always send default values in requests, and guardrail-generated servers will always send default values in responses (that is, they'll never be null or missing). the only time default values come into play on deserialization will be when someone is using a hand-rolled client, or is using curl or something to test things
(i do agree that it'd probably be better if clients never sent fields with defaults when they're unset, and just relied on the server to fill them in, but i don't think it's critical that things behave that way.)
blast_hardcheese
@blast_hardcheese:matrix.org
[m]
that's true. The ideal client behaviour is to not include the field at all if it's not customized, letting the missing key be filled in by the server
but then that once again gets into a sticky situation regarding encoders and decoders
for your purposes, if there's a way in the code to explicitly test for presence or absence of the key and set the default explicitly in both cases, that will make it easier to solve the more general case of presence/absence without having to revisit this from first principles, especially with the javaparser AST being as tricky as it is to read
kelnos
@kelnos:matrix.org
[m]
there isn't, at least not without generating manual ser/deser classes, rather than just using the annotations like i am now. i do plan to do this eventually, though, since supporting required=false,nullable=true requires it
blast_hardcheese
@blast_hardcheese:matrix.org
[m]
hmm, I meant at the point where facts have been gathered and you start to do codegen for those encoders/decoders
I think having a codec settings implicit which influences the manual encoders and decoders, as you mention, is going to be the ticket. What will be nice is memoizing those at the edge, since they only need to get resolved once. Previously I had written that off because it would be too much churn, but caching them in the clients and servers will fix that
kelnos
@kelnos:matrix.org
[m]
hm that's an interesting idea
java of course doesn't have implicits, so might be more challenging to implement that there
blast_hardcheese
@blast_hardcheese:matrix.org
[m]
Maybe thread locals?
That might not make sense, but just an idea
kelnos
@kelnos:matrix.org
[m]
ehhhhh
on the client it might be workable; client could somehow pass the deserializer to use at deser time to jackson
but on the server side, there's really no way to do that, as DW hides all that
blast_hardcheese
@blast_hardcheese:matrix.org
[m]
you can't DI your own mapper?
I find that very strange if true
kelnos
@kelnos:matrix.org
[m]
i can't from guardrail
blast_hardcheese
@blast_hardcheese:matrix.org
[m]
Oh right
Not without a guardrail module
kelnos
@kelnos:matrix.org
[m]
the user can do that if they want, though, but that's another thing that we'd have to require they register on their own
right
which isn't unprecendented. until recently i required a guardrail module for datetime types
(no longer required, but it used to be)
but the difference there is that if you didn't register that, you got very clear runtime failures
blast_hardcheese
@blast_hardcheese:matrix.org
[m]
Right
kelnos
@kelnos:matrix.org
[m]
with this type of thing you would get no failures, just silently subtly incorrect deser
blast_hardcheese
@blast_hardcheese:matrix.org
[m]
otoh we could barf at mount time if we recognize we don't have a module registered
again not a great idea
but technically possible.
kelnos
@kelnos:matrix.org
[m]
hmmm
not really; we don't have access to the ObjectMapper from the route class
(tho i wonder if DW lets you @Inject one into the class...)
i kinda do like the idea of setting up the POJOs with annotations that specify the "server (de)serializer", and that will just work, but in the client i can just pass a custom (de)serializer when calling the objectmapper
i think you can do that. not 100% sure. but i think so.
blast_hardcheese
@blast_hardcheese:matrix.org
[m]
I don't super like the idea of "default client unless known server", since any break in the chain switches semantics
kelnos
@kelnos:matrix.org
[m]
it's not great, but i don't see a better way to do it
blast_hardcheese
@blast_hardcheese:matrix.org
[m]
yeah
(also, I read your comment backwards -- my objection still stands, but I at least better understand what you mean)
kelnos
@kelnos:matrix.org
[m]
right. it's default server unless known client
kelnos
@kelnos:matrix.org
[m]
there's also perhaps a question around behavior of required=true,nullable=false properties when a default is present. like, i could see the argument that a client could actually leave that property out entirely, because the server should know about the default, and automatically fall back (so these sorts of properties automatically get 'demoted' to required=false,nullable=false). but maybe you want to think of it as more of a "UX default": the server will barf if you don't include it, and the default there is mainly to make it so the user of the client doesn't have to explicitly fill in the property (because the client can do it for them).
(my preference is for the latter behavior, to be clear)
blast_hardcheese
@blast_hardcheese:matrix.org
[m]

At the risk of making the wrong gut decision here, but required=true,nullable=false with a default should have the default injected by the server before the user sees it, regardless of presence in the actual wire encoding. If that means translating that into required=false,nullable=false then so be it.

The expectation would then be that removing the default from the spec would cause the generated code to change and a compiler error to be emitted.

kelnos
@kelnos:matrix.org
[m]
oh agreed. but i'm talking about client requests there, not server responses
blast_hardcheese
@blast_hardcheese:matrix.org
[m]
I think this would give the best experience for consumers -- smaller wire encoding, server-enforced defaults, and no trickery about secret defaults smuggled around in builders
kelnos
@kelnos:matrix.org
[m]

i'm still struggling a bit, though. the more i think about it... well, take the most "flexible" case, required=false,nullable=true. that's our tri-state of absent, null, or present. if i think about reflecting the intent of the user of the client, i would say that leaving things as absent would mean the client is saying "i don't care", and the server should assume the default value. if the client explicitly sends null, then i would think the client is saying "really, i mean no value here", and the server should not substitute the default.

if we accept that as reasonable -- maybe we won't, but let's assume we will, then what does that mean for the other two non-trivial cases?

required=false,nullable=false with a default still makes sense. if the client leaves the field empty, that still sounds like the "i don't care" case, and the server should substitute the default value.

but does required=true,nullable=true with a default even make sense here? if the client says null, then the server should probably see that and be like "ok, client says and means no value"? maybe this is purely a "UX default" again: the client exposes API to say "explicitly send a null", or "explicitly send a value", and if the user chooses neither of those, then the client sends the default value?

but maybe thinking about this with "intent" in mind isn't the right approach; maybe this is all about wire format. maybe someone doesn't like leaving fields out, and so "whatever": null really does mean (to the server) "substitute the default if you see null".

blast_hardcheese
@blast_hardcheese:matrix.org
[m]
In a tri-state world, we must assume that we're talking about presence and absence of fields, not presence or absence of values
1 reply
kelnos
@kelnos:matrix.org
[m]
but going back to your example above about the server-side stuff, i think that's interesting. are you saying in the required=true,nullable=false case, that the server should accept a request where the field is missing (or maybe eve null), but substitute the default when calling the handler? that seems a little weird to me, because to me the required/nullable knobs to me talk about the wire format, and required=true,nullable=false means that a request where that field is missing or null is an invalid request
blast_hardcheese
@blast_hardcheese:matrix.org
[m]
Yeah, sorry -- shorthand -- I was attempting to respond to your "whatever": null example wherein you say "substitute the default if you see null"