How would you implement a rest api `PATCH` method ...
# announcements
f
How would you implement a rest api
PATCH
method where clients can update the properties they want. `null`would be also an allowed value. I'm using the jackson mapper currently and "property not send" and "property is `null`" looks currently the same when using a normal `data`class.
a
When we had the same problem, there were two proposed methods that different teams used. AFAIK both teams are happy with their approach: • Use a
sealed class
with
Null
,
Undefined
, and
Present
constructors. You can define the usual
map
and
flatMap
methods on that class for convenience. You'll have to implement a deserialisation mechanism yourself. We implemented a custom jackson deserialiser. It's not really all that difficult • You can use an
Optional
in combination with
null
. Something like
Optional<T>?
or
Optional<T?>
depending on what you want. I think the latter is the more useful abstraction. I think you'll have to be creative with deserialisation again, though.
👍 1
c
is there definitely no way to annotate fields or a class to include null values?
@JsonInclude(Include.NON_NULL)
looks like there would be an
Include.NULL
also maybe
a
You have to be able to differentiate three cases: the user didn't specify the property at all (undefined) the user explicitly specified this property to be null, and the user specified this property to be something specific (of any type
T
.) Since you want to differentiate these three cases, you cannot just use null deserialisation, because the runtime representation of something being
null
doesn't tell you whether it was explicitly set to
null
or whether its specification was absent from the request.
k
third but definately not the best one would be to deserialize to
Map
a
You lose type safety that way (especially because it has to be a
Map<String, Any?>
) but for a prototype it might be ok.
Also, working with nested objects (i.e. nested nullable maps) is quite ok in JS, but a huge PITA in Kotlin 😄
i
to handle this issue, i created an Update<T> class which contains a T (to describe the values of fields that are being set, with type-safety) and removeFields (set of field names being removed/set to null), then wrote a Jackson deserializer for Update that understands the difference between a field being present/null and being absent. have the (java) deserializer code around if you want it