As was once said by Phil Karlton:
There are only two hard things in Computer Science: cache invalidation and naming things
In my exploration of caching in the last few days, I've come across issues with caching which makes me appreciate this on a whole new level - including the "who is in charge?" question you posed.
For simplicity - let's assume the server is totally in charge -
even then we have dilemmas.
For instance - we have a route to retrieve inventory items, which is filterable - GET
https://api.jiwa.com.au/Queries/Invento ... No&Take=25This would return 25 part numbers starting with the letter 'a'.
So, anyone calling that route will either get a cached result or a fresh result. Let's assume the cache expiry is set to 1 hour, so the first visit is fresh, thereafter it is cached until it expires in 1 hour and after that a fresh result is returned.
We also have our route to retrieve a single inventory item, GET
https://api.jiwa.com.au/Inventory/{InventoryID} - the same rule applies with caching - so the first visit is fresh, thereafter it is cached until it expires in 1 hour and after that a fresh result is returned.
If someone in Jiwa updates the description for that product, the REST API plugin hooks into the Inventory SaveEnd event and updates the cache entry for that item (if it was cached) with the new value. No problem there - anyone requesting a GET on the
https://api.jiwa.com.au/Inventory/{InventoryID} route using that ID will get the new value from the cache.
But what about the GET
https://api.jiwa.com.au/Queries/Invento ... No&Take=25 route? It doesn't know about the change. And it would no longer have a valid response - the description for that item might be incorrect.
This is a trivial example, and product descriptions being stale by at worst 1 hour might not be worth worrying about, but one can easily imagine situations where this might become a problem - a product deleted for instance might still be able to be added to a webstore cart as the user could select it from a list returned by the InventoryItemList, but POSTing to the /SalesOrders route would throw an exception.
I'm just thinking out loud here - just expressing some of the issues we're grappling with.