-
-
Notifications
You must be signed in to change notification settings - Fork 100
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
Serialize/Deserialize required fields as default (null or false) #1128
Comments
You can write own custom codecs if your project have a small number of such models that do not evolve a lot. But for generic case a better approach is to have classes for JSON messages that match requests as much as possible and keep them separated from your model classes: case class Person(name: String, dob: LocalDate, isApplicant: Boolean) // data model
case class PersonUpdate(name: Option[String], dob: Option[LocalDate], isApplicant: Option[Boolean]) // request footprint Then using such kind of libraries like chimney you can easily apply optional updates. Keeping those request classes and data model classes separately will allow to evolve them independently that will simplify development a lot. As an example, you can add the |
Our initial plan was to keep a separate class for request as you give example as. The issue was the model was so huge that we were wasting time on mapping and error prone. To reduce time, we ended up writing a JsonMerger that handle "null", "nil" etc. Nobody researched on chimney that time, may be because of the time crunch, looks excellent, may be I will do a POC on it and propose some ideas to the team. Thanks a lot for the reply and the library is amazing to work with! I am working around a temporary solution, we will keep the merger, probably use Json4s for parsing the request but use jsoniter-scala for database model. |
We needed to differentiate between the request nulling a field (an optional field) vs not providing. When not provided, we want to keep the backend value which is doable. But I think nulling also would keep the backend value when we must clear the backend field. Anyway we can override the null parsing behavior for optional fields? Using Json4s parsing, we get JNull and we use that for the merge to work correctly. |
It could be modeled clearly by the following sum type (instead of sealed trait Action[T+]
case object Hold extends Action[Nothing]
case object Clear extends Action[Nothing]
case class Update(v: T) extends Action[T] With a custom codec that will parse case class PersonUpdate(name: Action[String] = Hold, dob: Action[LocalDate] = Hold, isApplicant: Action[Boolean] = Hold) I can add a runnable example to tests of jsoniter-scala-macros module if you interested to see that approach in details, but for that modification there are no patching macros for transformation yet. |
This is great and yes I would like to see the custom codec on handling the null. So if you can give more details, would help! |
@kachaps4u Before preparing a detailed example for
|
|
The difference between
Yes, but no need to write them manually we can generate them using simple macros that works with mirrors for sum/ product types and required types of collections. BTW, how do you merge collections with updates, could you please give some examples? |
got it, I like the Option[Option for sure, less code. About the collection, that's something I wanted to bring up actually. For Seq/List => if field not provided, keep backend else if field provided and null, then clear else update
So below is possible: With a request: |
So Seq/List instances can be reset or updates as whole collections only, but Map instances can be updated as whole collections or per key-value pair (entry) basis? |
That's correct |
Hello!
We have an API that need to merge the request with the backend data. So potentially the request can have null fields that are required.
eg:
Person(name: String, dob: LocalDate, isApplicant:Boolean)
Backend data:
{ "name": "Name", "dob": "2017-06-30", "isApplicant": true }
New request:
{ "name": "NewName" }
By new request, we want to only update "name" field in the backend but keep the rest of the fields as backend value. This works with Json4s as null fields can be configured to null and we have a merge function to merge correctly. Using jsoniter-scala, per the documentation:
Is there anyway we can get around this in jsoniter-scala other than changing all data models to make all optional fields?
The text was updated successfully, but these errors were encountered: