Caching¶
[1] Ocelot currently supports caching on the URL of the downstream service and setting a TTL in seconds to expire the cache. Users can also clear the cache for a specific region by using Ocelot’s Administration API.
Ocelot utilizes some very rudimentary caching at the moment provider by the CacheManager project. This is an amazing project that is solving a lot of caching problems. We would recommend using this package to cache with Ocelot.
The following example shows how to add CacheManager to Ocelot so that you can do output caching.
Install¶
First of all, add the following Ocelot.Cache.CacheManager package:
Install-Package Ocelot.Cache.CacheManager
This will give you access to the Ocelot cache manager extension methods. The second step is to add the following to your Program:
using Ocelot.Cache.CacheManager;
builder.Services
.AddOcelot(builder.Configuration)
.AddCacheManager(x => x.WithDictionaryHandle());
CacheOptions Schema¶
Class: FileCacheOptions
The following is the full caching configuration, used in both the Route Schema and the Dynamic Route Schema.
Not all of these options need to be configured; however, the TtlSeconds option is mandatory.
"CacheOptions": {
"TtlSeconds": 1, // nullable integer
"Region": "", // string
"Header": "", // string
"EnableContentHashing": false // nullable boolean
}
Option |
Description |
|---|---|
|
Time-To-Live (TTL) in seconds for the cached downstream response, i.e., the absolute expiration timeout starting from when the item is added to the cache. This option is required. If undefined, it defaults to 0 (zero), which disables caching. |
|
Specifies the cache region to be cleared via Ocelot’s Administration API.
See: |
|
Specifies the header name used for native Ocelot caching control, defaulting to the special |
|
Toggles inclusion of request body hashing in the cache key.
Disabled by default ( |
The actual CacheOptions schema with all the properties can be found in the C# FileCacheOptions class.
Configuration¶
Finally, in order to use caching on a route in your route configuration add these sections:
"CacheOptions": {
"TtlSeconds": 15,
"Region": "europe-central",
"Header": "OC-Cache-Control",
"EnableContentHashing": false // my route has GET verb only, assigning 'true' for requests with body: POST, PUT etc.
},
// Warning! FileCacheOptions section is deprecated! -> use CacheOptions
"FileCacheOptions": {
"TtlSeconds": 15,
"Region": "europe-central",
"Header": "OC-Cache-Control",
"EnableContentHashing": false // my route has GET verb only, assigning 'true' for requests with body: POST, PUT etc.
}
In this example,
TtlSecondsis set to 15, which means the cache will expire 15 seconds after the response is stored.The
Regionproperty specifies a cache region. Cache entries within a region can be cleared by calling Ocelot’s Administration API.If a header name is defined in the
Headerproperty, its value is retrieved from theHttpRequestheaders. If the header is present, its value is included in the cache key constructed by theICacheKeyGeneratorservice. Varying header values result in different cache keys, effectively invalidating the cache.Finally,
EnableContentHashingis disabled due to the current route using theGETverb, which does not include a request body.
Warning
According to the static Route Schema, the FileCacheOptions section has been deprecated!
The old schema FileCacheOptions section is deprecated in version 24.1!
Use CacheOptions instead of FileCacheOptions! Note that FileCacheOptions will be removed in version 25.0!
For backward compatibility in version 24.1, the FileCacheOptions section takes precedence over the CacheOptions section.
EnableContentHashing option [2]¶
Previously, in versions prior to 23.0, the request body was used to compute the cache key. However, due to potential performance issues arising from request body hashing, it has been disabled by default. Clearly, this constitutes a breaking change and presents challenges for users who require cache key calculations that consider the request body (e.g., for the POST method). To address this issue, it is recommended to enable the option either at the route level or globally in the “Global Configuration” section:
"CacheOptions": {
// ...
"EnableContentHashing": true
}
Ocelot Team Recommendation
Although the community raised concerns about backward compatibility in issue 2234, Ocelot team maintains that caching performance takes precedence over backward compatibility when migrating from versions prior to 23.0.
The proposed option clarifies that POST requests should not be cached; only GET requests are eligible for caching.
Therefore, POST and GET verbs must be separated into distinct routes:
POST routes with caching disabled
GET routes with caching enabled
Global Configuration [3]¶
Copying route-level properties for each static route is no longer necessary, as version 23.3 allows these values to be set in the GlobalConfiguration section.
This convenience applies to Header and Region as well.
However, if no global TtlSeconds value is defined, this option must still be explicitly set per route to enable caching.
As a result, the final configuration for static routes might look like:
{
"Routes": [
{
"Key": "R0", // optional
"CacheOptions": {
"TtlSeconds": 60 // 1-minute short-term caching
},
// ...
},
{
"Key": "R1", // this route is part of a group
"CacheOptions": {}, // optional due to grouping
// ...
}
],
"GlobalConfiguration": {
"BaseUrl": "https://ocelot.net",
"CacheOptions": {
"RouteKeys": ["R1",], // if undefined or empty array, opts will apply to all routes
"TtlSeconds": 300 // enable global caching for a duration of 5 minutes
},
// ...
}
}
Dynamic routes were not supported in versions prior to 24.1.
Starting with version 24.1, global cache options for Dynamic Routing were introduced.
These global options may also be overridden in the DynamicRoutes configuration section, as defined by the Dynamic Route Schema.
{
"DynamicRoutes": [
{
"Key": "", // optional
"ServiceName": "my-service",
"CacheOptions": {
"TtlSeconds": 60 // 1-minute short-term caching
}
}
],
"GlobalConfiguration": {
"BaseUrl": "https://ocelot.net",
"DownstreamScheme": "http",
"ServiceDiscoveryProvider": {
// required section for dynamic routing
},
"CacheOptions": {
"RouteKeys": [], // or null, no grouping, thus opts apply to all dynamic routes
"TtlSeconds": 300 // enable global caching for a duration of 5 minutes
}
}
}
In this configuration, a 5-minute caching duration is applied to all implicit dynamic routes. However, for the “my-service” service, the caching TTL has been explicitly reduced from 5 minutes to 1 minute.
Note
1. If the RouteKeys option is not defined or the array is empty in the global CacheOptions, the global options will apply to all routes.
If the array contains route keys, it defines a single group of routes to which the global options apply.
Routes excluded from this group must specify their own route-level CacheOptions.
2. Prior to version 23.3, global CacheOptions were not available.
Starting with version 24.1, global configuration is supported for both static and dynamic routes.
Custom Caching¶
If you want to add your own caching method, implement the following interfaces and register them in DI e.g.
builder.Services
.AddSingleton<IOcelotCache<CachedResponse>, MyCache>();
IOcelotCache<CachedResponse>this is for output caching.IOcelotCache<FileConfiguration>this is for caching the file configuration if you are calling something remote to get your config such as Consul.
Roadmap¶
Please dig into the Ocelot source code to find more. We would really appreciate it if anyone wants to implement Redis, Memcached etc. Please, open a new Show and tell thread in Discussions space of the repository.