Starting in ASP.NET Core 7+, Microsoft introduced built-in Output Caching Middleware, which is the best way to cache full API responses.
In Program.cs:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOutputCache();
var app = builder.Build();
app.UseOutputCache();
app.MapControllers();
app.Run();
[HttpGet]
[OutputCache(Duration = 60)]
public IActionResult GetProducts()
{
return Ok(GetProductsFromDatabase());
}
🔹 This caches the response for 60 seconds.
🔹 Works great for GET endpoints.
builder.Services.AddOutputCache(options =>
{
options.AddPolicy("MyPolicy", policy =>
policy.Expire(TimeSpan.FromMinutes(5))
.SetVaryByQuery("category"));
});
Then:
[OutputCache(PolicyName = "MyPolicy")]
This uses HTTP headers like Cache-Control. It works with browser/proxy caching.
builder.Services.AddResponseCaching();
app.UseResponseCaching();
[ResponseCache(Duration = 60)]
[HttpGet]
public IActionResult GetProducts()
{
return Ok(data);
}
🔹 This sets HTTP headers.
🔹 It does NOT cache on the server by default.
🔹 Good for public APIs.
In-Memory Caching (IMemoryCache)
Best when you want to cache data, not full HTTP responses.
builder.Services.AddMemoryCache();
private readonly IMemoryCache _cache;
public ProductsController(IMemoryCache cache)
{
_cache = cache;
}
[HttpGet]
public IActionResult GetProducts()
{
if (!_cache.TryGetValue("products", out List<Product> products))
{
products = GetProductsFromDatabase();
var cacheOptions = new MemoryCacheEntryOptions()
.SetSlidingExpiration(TimeSpan.FromMinutes(5));
_cache.Set("products", products, cacheOptions);
}
return Ok(products);
}
For multi-server environments, use distributed cache.
Common choice:
-
Redis: Redis can store complex data types like Lists, arrays, Hash tables etc.
Memcached: Simple text string store
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = "localhost:6379";
});
Then inject IDistributedCache.
| Feature | Memcached | Redis |
|---|---|---|
| Distributed | Yes | Yes |
| Replication | No (basic) | Yes |
| Persistence | No | Yes |
| Data loss risk | Higher | Lower |
| Complexity | Simple | Advanced |
| Scenario | Recommended |
|---|---|
| Cache full API response | OutputCache |
| Scale across multiple servers | Redis (Distributed Cache) |
| Cache DB results only | IMemoryCache |
| Browser/proxy caching | ResponseCache |
- Cache only GET requests.
- Avoid caching user-specific data unless using
VaryBy. - Always define expiration.
- Invalidate cache on data update.
- Use distributed cache in production with multiple instances.
| Feature | Response Caching | Output Caching |
|---|---|---|
| Where caching happens | Client / Proxy (browser, CDN) | Server (inside ASP.NET Core) |
| Middleware | UseResponseCaching() | UseOutputCache() |
| Actually stores response on server? | No | Yes |
| Performance benefit for server | Minimal | Significant |
| Best for | Public APIs | High-performance APIs |
| Introduced | Early ASP.NET Core versions | .NET 7 |
No comments:
Post a Comment