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
CacheKeydecorator 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
GETmethod 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/petsresults in a cache key of/pets, whilehttp://localhost:3000/pets?search=testyields 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
nullorundefined, the interceptor returns a response with the received value (step2ain the diagram). - If the value is
nullorundefined, indicating a cache miss (step2bin the diagram), the interceptor taps into the handle observable method, searching for the response and setting that response in the cache (step4bin 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:
