В ASP.NET WebAPI существует несколько способов реализации кэширования HTTP-ответов:
[OutputCache(Duration = 60)] // Кэшировать на 60 секунд
public HttpResponseMessage Get(int id)
{
var product = _repository.GetProduct(id);
return Request.CreateResponse(HttpStatusCode.OK, product);
}
private static MemoryCache _cache = new MemoryCache(new MemoryCacheOptions());
public IHttpActionResult Get(string key)
{
if (_cache.TryGetValue(key, out var cachedData))
{
return Ok(cachedData);
}
var data = GetExpensiveData();
_cache.Set(key, data, TimeSpan.FromMinutes(10));
return Ok(data);
}
public HttpResponseMessage Get()
{
var response = Request.CreateResponse(HttpStatusCode.OK, GetData());
response.Headers.CacheControl = new CacheControlHeaderValue
{
MaxAge = TimeSpan.FromSeconds(3600),
MustRevalidate = true,
Public = true
};
return response;
}
public HttpResponseMessage Get(int id)
{
var product = _repository.GetProduct(id);
var etag = $"\"{product.Version}\""; // Уникальный идентификатор версии
if (Request.Headers.IfNoneMatch.Any(h => h.Tag == etag))
{
return Request.CreateResponse(HttpStatusCode.NotModified);
}
var response = Request.CreateResponse(HttpStatusCode.OK, product);
response.Headers.ETag = new EntityTagHeaderValue(etag);
return response;
}
public class ProductsController : ApiController
{
private readonly IDistributedCache _cache;
public ProductsController(IDistributedCache cache)
{
_cache = cache;
}
public async Task<IHttpActionResult> Get(int id)
{
var cacheKey = $"product_{id}";
var cachedProduct = await _cache.GetStringAsync(cacheKey);
if (cachedProduct != null)
{
return Ok(JsonConvert.DeserializeObject<Product>(cachedProduct));
}
var product = _repository.GetProduct(id);
await _cache.SetStringAsync(cacheKey,
JsonConvert.SerializeObject(product),
new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30)
});
return Ok(product);
}
}
Для ASP.NET Core WebAPI:
[ResponseCache(Duration = 60, Location = ResponseCacheLocation.Client)]
[HttpGet("{id}")]
public ActionResult<Product> GetById(int id)
{
return _repository.GetProduct(id);
}
public class CacheAttribute : ActionFilterAttribute
{
public int Duration { get; set; }
public override void OnActionExecuted(HttpActionExecutedContext context)
{
if (context.Response != null)
{
context.Response.Headers.CacheControl = new CacheControlHeaderValue
{
MaxAge = TimeSpan.FromSeconds(Duration),
MustRevalidate = true,
Public = true
};
}
}
}
// Использование:
[Cache(Duration = 3600)]
public IHttpActionResult Get() { ... }
public class ProductsController : ApiController
{
[OutputCache(Duration = 3600, VaryByParam = "category")]
public HttpResponseMessage GetByCategory(string category)
{
// ...
}
}
В ASP.NET WebAPI доступны различные механизмы кэширования - от простых атрибутов OutputCache до сложных распределенных систем. Выбор подхода зависит от требований приложения: для простых сценариев достаточно серверного кэширования, для сложных распределенных систем лучше использовать IDistributedCache с настройкой соответствующих заголовков HTTP для клиентского кэширования.