I maintain an application which helps users to track the progress of an activity in real time. In essence, we represent the state of said activity as a data class in the Android mobile app. Every time some aspect of the activity changes, either in the client or the server, the whole representation of the activity is sent as the body of an API request or response. What would be an effective way to instead only send and receive the aspects of the activity state (i.e., the properties of the instance of the data class that are meant to be updated)?
For example, having the following:
data class Contact(val firstName: String, val middleName: String?, val lastName: String)
And an instance like below:
Contact(firstName=John, middleName=null, lastName=Doe)
We receive:
{ firstName: "Jane" }
Then how do we obtain...?
Contact(firstName=Jane, middleName=null, lastName=Doe)
Of course this is a very simple example, but consider data classes with many more fields and properties with more complex types.
It seems to me quite a general problem to solve, but I have not found any references on what a practical approach could be. A few high-level approaches came to mind:
- Have a diff data class which was identical to the original but which only had optional (nullable) parameters and then a function that could copy the original instance replacing only the values set in the diff.
- Represent the difference as something other than a data class, like a map or a json object, and manually map and (de)serialize each value into a copy of the original instance.
The main problem with the first approach is that it does not immediately solve the scenario in which the change consists of a property being unset (i.e., set to null) which may require a workaround, like wrapping nullable properties as optional in the diff class. The second approach may be more flexible, but it will likely require more code and be harder to maintain.