Nest: Cannot set infinite TTL on cached endpoint with @CacheTTL Decorator

Created on 29 Mar 2020  路  5Comments  路  Source: nestjs/nest

Bug Report

Current behavior

The cache TTL decorator does not allow for a way to set an infinite TTL (ie no expiry time) on a cached endpoint. Typically with the underlying cache manager, an infinite TTL would be set by passing in a value of zero. However, the cache TTL decorator ignores this and defaults to the global TTL value instead.

Input Code

Code Sandbox Here

The global TTL is set to 5 seconds. The endpoint being cached is in app.controller.ts. I have written really simplistic tests to illustrate the issue in app.controller.spec.ts.

Expected behavior

The Cache TTL decorator should allow for a way to set an infinite TTL on a cached endpoint. Ideally, this would be done by setting the TTL to 0 which would mimic the same behaviour as the underlying cache manager.

Possible Solution

I believe this issue arises because of line 53 in packages/common/cache/interceptors/cache.interceptor.ts:
const args = ttl ? [key, response, { ttl }] : [key, response];

This expression returns falsey when the ttl variable is 0 which means that the TTL config for the key is taken from the global settings instead of being set to 0.

Environment


Nest version: 7.0.6

Others:
Cache Manager version: 3.2.1
common type

Most helpful comment

@Mario857 My reason for preferring to not do it that way is that it doesn't follow node cache manager's convention which allows for a TTL of 0 to mean a non-expring cache. This, in turn, is based on the lru-cache package which is used under the hood.

I think a neat alternative for no cache on an endpoint when a global cache is set could be to maybe implement a NoCache decorator? However, I think that should be raised in a separate thread.

What are your thoughts @kamilmysliwiec?

All 5 comments

Would you like to create a PR for this issue :)?

I would like to! I'll try to submit one by the end of this coming week :)

@Emily-RoseSteyn @kamilmysliwiec I was thinking about it since I come across same problem but something like this would be nice @CacheTTL(Infinity) to set infinite cache and @CacheTTL(0) to disable cache (useful when using cache interceptor on global scope)
I will create pr if you agree

@Mario857 My reason for preferring to not do it that way is that it doesn't follow node cache manager's convention which allows for a TTL of 0 to mean a non-expring cache. This, in turn, is based on the lru-cache package which is used under the hood.

I think a neat alternative for no cache on an endpoint when a global cache is set could be to maybe implement a NoCache decorator? However, I think that should be raised in a separate thread.

What are your thoughts @kamilmysliwiec?

My reason for preferring to not do it that way is that it doesn't follow node cache manager's convention which allows for a TTL of 0 to mean a non-expring cache. This, in turn, is based on the lru-cache package which is used under the hood.

I think we should follow the cache manager convention for the sake of consistency 馃憤

I think a neat alternative for no cache on an endpoint when a global cache is set could be to maybe implement a NoCache decorator? However, I think that should be raised in a separate thread.

We discussed a NoCache decorator in the past and decided to avoid introducing more decorators. To exclude a specific set of endpoints, one can always inherit from the CacheInterceptor and use the ExecutionContext there. Old example: https://github.com/nestjs/nest/issues/1050#issuecomment-418639184

Was this page helpful?
0 / 5 - 0 ratings

Related issues

menme95 picture menme95  路  3Comments

mishelashala picture mishelashala  路  3Comments

marshall007 picture marshall007  路  3Comments

cdiaz picture cdiaz  路  3Comments

yanshuf0 picture yanshuf0  路  3Comments