0

Currently I have following scenario.

I have two projects: ASP.NET Core Web API and Xamarin.Forms app. General idea is to have consumer (Xamarin.Forms app) which is getting data from server (Web API).

What I want to implement is caching pattern for the mobile app. Let's say, we're getting some products from the server and then we want to cache them, so next time when use open app he won't re-get all products again.

The problem is coming when these products are updated, then we want our mobile app to always stay with latest data, but still refresh products only if they're updated. For this I've considered using versioning on my database entities (products). For example, first time when app request to get product he will send version null header, then API will spot it, get from database product and return it with its version, for example 5. After that product could be updated, so version will be increased with one. When app send request to get product again, depending on provided in header version API will get latest data from database or return 304 NotModified status code.

While I was developing this scenario, I've decided to change "int version" to simply "DateTime lastModified", which I find for a little bit more useful.

My struggle is coming when I have scenario with multiple items, let's say I want to get all products from category. Then I am not sure what is the best case for solving that issue. I've considered to expect from consumer to send me collection with product id and last modified, so I can iterate through all of them and check if something has changed. Other option is to expect sending be hash of that collection, so on the server side I can hash searched collection and compare hashes. Third option is, if for each collection I have extra property which is containing last modified, but then I will have one extra column in database (SQL) for each many relation and then modifying product would require extra code, to find all it's relations and update all properties.

Generally my problem is when it comes to collections.

Still is this good way, for designing application? What I want to achieve, is reduce traffic between server and consumer.

I'm open for any other suggestions!

Thanks in advance!

2

The restful/HATEOS answer to this requirement is to use the etag header to store the version information.

ETag: "686897696a7c876b7e"

Whenever the client requests a cached resource, the etag header should be present in the response. It should always be the same value as long as the resources stay the same. When the resource gets updated, the etag should roll over to a new value.

To check to see if the resource has changed, the client can submit a If-None-Match header.

If-None-Match: "686897696a7c876b7e"

The server then looks at the header and checks to see if it matches the current etag value. If it does, it should respond with an HTTP 304 header ("not changed"). If it doesn't, the full resource is returned, along with a the new etag value. The client then caches the resource and the etag.

  • Hello, thank you for your answer. I think that's exactly what I need. My only question is, how's that going to work in the clustered solution. So from what I understand strong validation is what I need, where it's checking byte-by-byte. But what if I have API deployed to multiple app services, will it work in the same way? Thanks – Nikolay Dermendzhiev Mar 27 '18 at 15:58
  • Question seems off... you shouldn't be comparing anything and I'm not sure what you think needs to be validated. Isn't the file trusted content? Typically you'd need to store metadata somewhere, e.g. a database record containing the location of the latest file and its etag. Then you just retrieve the record, compare the tags, and serve the file if they don't match. – John Wu Mar 27 '18 at 17:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.