I saw this post today but I will answer anyway. Maybe it can help others.
Spring-boot uses by default CaffeineCache to cache service calls and it's very simple to use it. You just have to annotate your service method using @Cacheable. The example below caches the user permissions in a cache named "sso-users-cache" (because I don't want to call the service to check user's permissions all the time), creating an entry using company name (the system is multi-company) and userId, unless the method returns an error (remember: if you don't have a clausule unless, you can cache even an error of your service).
@Cacheable(cacheNames = ["sso-users-cache"], key = "#company.concat('-sso-user-').concat(#userId)", unless = "#result instanceof T(com.github.michaelbull.result.Err)")
fun fetchActionsByOrganizationAndUser(company: String, userId: String): Result<Set<String>, String> {
val response = Unirest
.get(getUserPermitionsUrl(company = company, userId = userId))
.header("Content-Type", "application/json")
.asString()
.ifFailure {
logger.error("SSO Error: Get user permissions failed: context: $company : userId: $userId")
}
return if(response.isSuccess) {
Ok(serializeUtil.asCollection(response.body, String::class.java).toSet())
} else {
Err("SSO Error: Get user permissions failed: context: $company : userId: $userId\"")
}
}
The parameter cacheNames defines an entry in your cache while the key, will tell the name of the entry on cache (it's used because users have different permissions and they need different entries inside the cache.
The parameter unless tells the cache to not cache if my method returns an error (very important!)
About update the cache informations, it's not necessary. What you need is to invalidate the cache information in case user's permission changes. For exemple, the method below add a new permission for the user and I need to invalidate (clear) the cache I have for the specific user:
@CacheEvict(cacheNames = ["sso-user-actions-cache"], key = "#company.concat('-user-actions-').concat(#userId)")
fun addPermissionToUser(company: String, userId: String, permission: String) {
Unirest
.put(addUserPermitionsUrl(company = company, userId = userId, permission = permission))
.header("Content-Type", "application/json")
.asEmpty()
}
Again: it's important to use the property key because I want to clear only the entry for a specific user!!! Otherwise, you will clean the whole permission cache (for all users)
After the @CacheEvict, the next call to check user's permission, spring will realize that the user doesn't have an entry on cache and will call the service and cache the return. That's it.