redarrowlabs / Argo

:squirrel: c# object => json.api relational mapping
MIT License
7 stars 3 forks source link

Meta is excessively patched because object is typically never fully equal #93

Closed zeitlerc closed 6 years ago

zeitlerc commented 6 years ago

Usually, the meta on the Fody model will be a subset of all meta being returned by the server. For example, my application is only interested in the created/updated timestamps while the server may return the users that performed the action as well. That causes issues in complex meta structures, since the current implementation only checks the equality of the 1st level property in meta. In this instance, the full contents of the "system" property are not equal and therefore will always be patched. In reality, the meta properties in the Fody class have not been changed, so the patch should not be sent.

// Contents of the Meta property
// Response from JsonApi
{
  "system": {
    "createdBy": "91773e2b-f121-435d-b3bf-be26cb3c9503",
    "createdAt": "2018-02-12T15:29:18.6158073Z",
    "updatedBy": "91773e2b-f121-435d-b3bf-be26cb3c9503",
    "updatedAt": "2018-02-12T16:01:56.8293298Z",
    "eTag": "\"0b0099b9-0000-0000-0000-5a81ba740000\""
  }
}
// Patch request produced by Argo
{
  "system": {
    "createdAt": "2018-02-12T15:29:18.6158073Z",
    "updatedAt": "2018-02-12T16:01:56.8293298Z",
    "eTag": "\"0b0099b9-0000-0000-0000-5a81ba740000\""
  }
}
zeitlerc commented 6 years ago

This issue started in #91 where we switched from tracking setters using Fody to doing diffs using JSON. That was a positive change overall and leads to a smaller patch body in the end since the consumer does not have to reset every complex property just to get one of them to update. At the time, I didn't want to commit to making a complex JSON diff tool and none of the existing libraries were particularly attractive, so the current implementation is very coarse-grained and somewhat inefficient. Optimally, we would either use a library like jsondiffpatch or roll our own simple, targeted solution to build the patch.

https://github.com/redarrowlabs/Argo/blob/5b2e19dca9d6ee9b062337052bc0740544f8dea9/src/RedArrow.Argo.Client/Session/Session.cs#L647