A distributed cache lets separate applications or instances read the same cached data, even when another instance populated it. Redis can provide that shared cache across physical machines. For a product catalog, this avoids a database round trip on every request for information that changes infrequently. section 7.3 section 7.4.3
A /products endpoint can use a cache-first flow:
- Register Redis with AddRedisDistributedCache() and inject IDistributedCache into the endpoint. section 7.4.3
- Call GetStringAsync() with a product-list key. If it returns a value, deserialize the JSON and return the products. section 7.4.3
- On a miss, query the database and store the resulting product data as a JSON string with SetStringAsync(). The next request can read it from the cache, regardless of which API instance receives it. section 7.4.3
- After adding, removing, or changing a product, call RemoveAsync() so the next retrieval repopulates the entry rather than returning the old list. section 7.4.3
Listing 7.3 Retrieving product items from the cache
app.MapGet("/products",
async ([FromServices] SqlConnection connection,
[FromServices] IDistributedCache cache) =>
{
const string cacheKey = "Products";
var cached = await cache.GetStringAsync(cacheKey); #1
if (cached is not null) #2
{
var cachedProducts =
JsonSerializer.Deserialize<ProductDto[]>(cached);
return Results.Ok(cachedProducts);
}
await connection.OpenAsync();
await using var command = new SqlCommand(@"
USE Shop;
SELECT Id, Title, Summary, Price
FROM Products;", connection);
var products = new List<ProductDto>();
await using var reader = await command.ExecuteReaderAsync();
while (await reader.ReadAsync())
{
products.Add(new ProductDto(
Id: reader.GetInt32(0),
Title: reader.GetString(1),
Summary: reader.GetString(2),
Price: reader.GetDecimal(3)
));
}
var serializedProducts = JsonSerializer.Serialize(products.ToArray());
await cache.SetStringAsync( #3
cacheKey,
serializedProducts,
new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5)
});
return Results.Ok(products.ToArray());
});
The /products endpoint listing shows the cache lookup alongside the database query it can avoid. section 7.4.3
A distributed cache can also support distributed locking: a named lock coordinates access to a shared resource across separate applications. That is a different use from caching product responses. section 7.3
