Would it be possible to create a response filter type functionality for the [CacheResponse] attribute?
So everytime before the CacheResponse functionality adds a response into the cache, I can intercept that request and decide if it’s something I actually want to be cached?
For example, I may have a boolean WasSuccessful that only when true I want to be cached. Or I may have a list of items, that only when the list is populated does the response get cached?
It could go something like this:
CacheResponseFilters.Add((req, res, dto) =>
{
var response = dto as IHasSuccessfulFlag;
if (response != null)
{
if(response.WasSuccessful)
return true; // save to cache
}
return false; // do not save to cache
});
So now when all the values in the chain are true, CacheResponse can do it’s thing. This allows a huge amount of flexibility without cluttering the code in the actual service.
Have a look at how the CacheResponse attribute works which just drops a populated CacheInfo into req.Items[Keywords.CacheInfo] which is what gets picked up by the HttpCacheFeature to cache the feature, so you can disable the caching of a Response by adding a Global Response Filter that just removes the CacheInfo object from IRequest.Items, e.g:
GlobalResponseFilters.Add((req, res, dto) =>
{
if (doNotSaveToCache)
req.Items.Remove(Keywords.CacheInfo);
});
Caching is already enabled with the [CacheResponse] filter attribute as its Request Filter is what checks to see if there’s a valid cache for the request and if there is returns the cache and short-circuits the response so the Service never gets executed. So “doing nothing” will cache the response leaving your Response Filter only needing to disable the cache when it needs to.
Note Feature Requests are best submitted to ServiceStack’s UserVoice so the request doesn’t get lost and we can measure demand for the feature and prioritize accordingly.
Sorry for the thread necromancy, but is there a way to short-circuit CacheResponse for something that’s already been cached? I.E. give the client an option (perhaps by header) to always retrieve a live version of the data? Or do I need to create dedicated endpoints for that?
It would be an DDOS issue if clients could automatically by-pass caching for any Service.
You should create “non-cached” versions of Services you want to allow clients to access, then you can use the Gateway to delegate cached Services to use your existing ones, see http://northwind.netcore.io Cached Services examples: