CacheCow is a great tool we can use In ASP.Net WebApi projects to maintain cache with SQL Server persistence. You can view how to implement CacheCow with SQL Server in this post.
However, there is a problem in the default implementation of invalidating cache if we have different kind of GET requests.
eg : Assume our GET request is http://myhost/api/customers. So a POST, PUT,PATCH or DELETE requests for same request http://myhost/api/customers would invalidate the cache.
But what if we have different formations of GET requests.
Eg :
GET : http://myhost/api/customers_country/SriLanka
GET : http://myhost/api/customers_city/Colombo
So any update request to http://myhost/api/customers would not invalidate cache of aforementioned GET requests.
Following is a very simple way of invalidate cache based on the root routing value.
I'm using hard coded sql here because this is a separate entity to my other business entities.
What all we need to do is call this method when ever there is an update to a resource.
However, there is a problem in the default implementation of invalidating cache if we have different kind of GET requests.
eg : Assume our GET request is http://myhost/api/customers. So a POST, PUT,PATCH or DELETE requests for same request http://myhost/api/customers would invalidate the cache.
But what if we have different formations of GET requests.
Eg :
GET : http://myhost/api/customers_country/SriLanka
GET : http://myhost/api/customers_city/Colombo
So any update request to http://myhost/api/customers would not invalidate cache of aforementioned GET requests.
Following is a very simple way of invalidate cache based on the root routing value.
I'm using hard coded sql here because this is a separate entity to my other business entities.
public class CacheCowHackService : ICacheCowHackService { public int InvalidateEntityCache(string parentPattern) { int noOfRowDeleted; using (var ctx = new MyContext()) { //Delete command noOfRowDeleted = ctx.Database.ExecuteSqlCommand( $"delete from CacheState where RoutePattern LIKE '%{parentPattern}%'"); } return noOfRowDeleted; } }
What all we need to do is call this method when ever there is an update to a resource.
public VehicleViewModel Create(VehicleViewModel model) { var id = Guid.NewGuid(); model.Id = id; using (var transactionScope = new TransactionScope()) { ...... var entity = VehicleMap.ModelToEntity(model); .... _vehicleService.Add(entity); entity = _vehicleService.GetSingle(x => x.Id == id); model = VehicleMap.EntityToModel(entity); CacheCowHack.InvalidateEntityCache(Const.VehicleRoute); transactionScope.Complete(); return model; } }
No comments:
Post a Comment