You've delved into the NestJS documentation on caching and found the Auto-caching responses section impressive. Just adding @UseInterceptors(CacheInterceptor)
above your route or controller magically enables caching for GET endpoints. But what if issues arise and you're unsure why? Or perhaps you're just curious about the mysterious workings under the hood. Let's explore what exactly happens when you add the CacheInterceptor
.
Consider the following controller code:
@Controller('pets')
export class PetsController {
constructor(private petsService: PetsService) {}
@UseInterceptors(CacheInterceptor)
@Get()
getAllPets(): string[] {
return this.petsService.getAllPets();
}
}
This PetsController
has a single GET method that retrieves all pets from the petsService
and returns them. Notice the @UseInterceptors(CacheInterceptor)
to enable auto-caching of responses on this endpoint.
Now, let's break down the process with the help of the diagram below:

Step 1: Get the Cache Key
- Attempt to retrieve the cache key provided by the developer.
- NestJS offers a
CacheKey
decorator for this purpose.
@CacheKey('get-pets') @UseInterceptors(CacheInterceptor) @Get() getAllPets(): string[] { return this.petsService.getAllPets(); }
- NestJS offers a
- If the developer-provided cache key is found, the function immediately returns it and proceeds to Step 2.
- If the developer-provided cache key is not found, the interceptor checks if the request is cacheable (by default, only
GET
method is allowed). If the method is anything other thanGET
, the function returnsundefined
, halting the caching process. - If the method is GET and the request is cacheable, NestJS generates a cache key based on the URL. For example,
http://localhost:3000/pets
results in a cache key of/pets
, whilehttp://localhost:3000/pets?search=test
yields a cache key of/pets?search=test
.
Step 2: Continuing the Cache Process if Key is Found
- Retrieve the value from the cache datastore using the obtained key.
- If the value is not
null
orundefined
, the interceptor returns a response with the received value (step2a
in the diagram). - If the value is
null
orundefined
, indicating a cache miss (step2b
in the diagram), the interceptor taps into the handle observable method, searching for the response and setting that response in the cache (step4b
in the diagram).
Note: Caching does not occur if the response is of type StreamableFile
.
That's it. If you wish to explore how it works yourself, check out the source code of the CacheInterceptor
.
References: