liveBook · Manning

Cache key

As explained in Building Web APIs with ASP.NET Core

A cache key is an identifier that distinguishes a cached entry associated with a particular request or data variant.

A cache key identifies the cached result for one request or data variant. In a board-game API, different GET parameters must produce different keys so one request cannot receive another request’s data. section 8.3.3

Implement a request-specific cache key by:

  • Creating a string from the request DTO’s type name and its JSON-serialized value. section 8.3.3
  • Checking the in-memory cache for that key before querying EF Core. section 8.3.3
  • Caching the retrieved board-game array for 30 seconds when no matching entry exists. section 8.3.3

Board-game GET request

A controller can form a key such as input.GetType() plus JsonSerializer.Serialize(input), then use TryGetValue<BoardGame[]> to reuse the matching result. section 8.3.3

Listing 8.6 BoardGamesController’s Get method
[HttpGet(Name = "GetBoardGames")]
[ResponseCache(CacheProfileName = "Any-60")]
public async Task<RestDTO<BoardGame[]>> Get(
    [FromQuery] RequestDTO<BoardGameDTO> input)
{
  _logger.LogInformation(CustomLogEvents.BoardGamesController_Get,
      "Get method started.");
 
var query = _context.BoardGames.AsQueryable();                         #1
if (!string.IsNullOrEmpty(input.FilterQuery))                        #2
query = query.Where(b => b.Name.Contains(input.FilterQuery));
 
var recordCount = await query.CountAsync();                           #3
 
BoardGame[]? result = null;                                            #4
var cacheKey = $"{input.GetType()}-{JsonSerializer.Serialize(input)}";#5
if (!_memoryCache.TryGetValue<BoardGame[]>(cacheKey, out result))     #6
{
query = query                                                  #7
.OrderBy($"{input.SortColumn} {input.SortOrder}")
.Skip(input.PageIndex * input.PageSize)
.Take(input.PageSize);
result = await query.ToArrayAsync();
_memoryCache.Set(cacheKey, result, new TimeSpan(0, 0, 30));
}
 
  return new RestDTO<BoardGame[]>()
  {
Data = result,                                                    #8
    PageIndex = input.PageIndex,
    PageSize = input.PageSize,
    RecordCount = recordCount,
    Links = new List<LinkDTO> {
      new LinkDTO(
        Url.Action(
          null,
          "BoardGames",
          new { input.PageIndex, input.PageSize },
          Request.Scheme)!,
        "self",
        "GET"),
    }
  };
}

Inspect the controller listing to follow key creation, cache lookup, and conditional EF Core retrieval in sequence. section 8.3.3

How Building Web APIs with ASP.NET Core covers it

How deep it goes
Defines key construction and cache-or-query flow, but does not develop broader cache-key design concerns.
Examples
Demonstrates a BoardGamesController key combining a request type name with serialized request data.
What it assumes
Assumes familiarity with controller GET parameters, DTOs, EF Core queries, and JSON serialization.
What you can do after
Apply it via IMemoryCache to prevent mismatched responses and avoid repeated EF Core queries.
How it connects
Connects in-memory caching with EF Core, data-transfer objects, GET parameters, and JSON serialization.

Also explained in

Compare how 3 books explain cache key →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Building Web APIs with ASP.NET Core. The section links point to the parts of the book it draws on.