Contact Us 1-800-596-4880

HTTP Caching Policy

Policy Name

HTTP caching

Summary

Caches HTTP responses from an API implementation

Category

Quality of Service

First Flex Gateway version available

v1.0.0

Returned Status Codes

No return codes exist for this policy

Summary

The HTTP Caching policy enables you to cache HTTP responses for reuse. Caching these responses speeds up the response time for user requests and reduces the load on the backend. For example, if your backend exposes an endpoint for which the responses to requests are not likely to change, you can reuse the HTTP responses and bypass the backend request processing by using the HTTP Caching policy.

Configuring Policy Parameters

Flex Gateway Local Mode

In Local Mode, you apply the HTTP Caching policy to your API via declarative configuration files. Refer to the following policy definition and table of parameters:

- policyRef:
    name: http-caching-flex
  config:
    httpCachingKey: <string> // REQUIRED, default: "#[attributes.requestPath]"
    maxCacheEntries: <int> // REQUIRED, default: 10000
    ttl: <int> // REQUIRED, default: 600
    useHttpCacheHeaders: <bool> // REQUIRED, default: true
    invalidationHeader: <string> // OPTIONAL, default: ""
    requestExpression: <string> // OPTIONAL, default: "#[attributes.method == 'GET' or attributes.method == 'HEAD']"
    responseExpression: <string> // OPTIONAL, default: "#[[200, 203, 204, 206, 300, 301, 404, 405, 410, 414, 501] contains attributes.statusCode]"
    distributed: <bool> // REQUIRED, default: false
    persistCache: <bool> // REQUIRED, default: false
Parameter Required or Optional Default Value Description

httpCachingKey

Required

#[attributes.requestPath]

A DataWeave expression

maxCacheEntries

Required

10000

Specifies the maximum number of entries that can be stored in the cache at any given time

ttl

Required

600

Specifies the amount of time (in seconds) after which a single entry expires from the cache

useHttpCacheHeaders

Required

true

Enables the use of Cache-Control header directives

invalidationHeader

Optional

Empty string

A string specifying the header used to invalidate a single entry or the entire cache

requestExpression

Optional

#[attributes.method == 'GET' or attributes.method == 'HEAD']

The DataWeave expression that is used to decide which requests are to be cached (caches the response only if the condition is true)

responseExpression

Optional

#[[200, 203, 204, 206, 300, 301, 404, 405, 410, 414, 501] contains attributes.statusCode]

The DataWeave expression that is used to decide which responses are to be cached (caches the response only if the condition is true)

distributed

Required

false

Configures the cache to be distributed among different nodes in a cluster

persistCache

Required

false

Configures the cache to persist between different restarts of the replica

Leaving a required value blank configures the parameter as the default value. No value is configured for optional values left blank.

Resource Configuration Example

- policyRef:
    name: http-caching-flex
  config:
    httpCachingKey: "#[attributes.requestPath]"
    maxCacheEntries: 10000
    ttl: 500
    useHttpCacheHeaders: false
    requestExpression: "#[attributes.method == 'GET' or attributes.method == 'HEAD']"
    responseExpression: "#[[200, 203, 204, 206, 300, 301, 404, 405, 410, 414, 501] contains attributes.statusCode]"

Distributed Caching Resource Configuration Example

Distributed Caching requires Shared Storage to be enabled. For more information about Shared Storage, refer to Configuring Shared Storage for Flex Gateway in Connected Mode.

---
apiVersion: gateway.mulesoft.com/v1alpha1
kind: Configuration
metadata:
  name: shared-storage-redis
spec:
  sharedStorage:
    redis:
      address: redis:6379
      user: user
      password: pass
      DB: 1

---
apiVersion: gateway.mulesoft.com/v1alpha1
kind: PolicyBinding
metadata:
  name: ingress-http-caching
spec:
  targetRef:
    kind: ApiInstance
    name: ingress-http
  policyRef:
    kind: Extension
    name: http-caching-flex
  config:
    httpCachingKey: "#[attributes.method ++ attributes.requestPath]"
    useHttpCacheHeaders: true
    maxCacheEntries: 100
    ttl: 600
    distributed: true
    persistCache: true
    invalidationHeader: AGW-CACHE-CONTROL

Flex Gateway Connected Mode

When you apply the HTTP Caching policy to your API from the UI, you can configure the following parameters:

Parameter Description Required?

HTTP Caching Key

A DataWeave expression. Default value: #[attributes.requestPath]

Yes

Maximum Cache Entries

Specifies the maximum number of entries that can be stored in the cache at any given time. Default value: 10000

Yes

Entry Time To Live

Specifies the amount of time (in seconds) after which a single entry expires from the cache. Default value: 600

Yes

Distributed

Configures the cache to be distributed among different nodes in a cluster. Default value: false

Yes

Persistent Cache

Configures the cache to persist between different restarts of the Flex Gateway instance. Default value: false

Yes

Follow HTTP Caching directives

Enables the use of Cache-Control header directives. Default value: true

Yes

Invalidation Header

Name of the header used to invalidate a single entry or the entire cache.

No

Conditional Request Caching Expression

The DataWeave expression that is used to decide which requests are to be cached (caches the response only if the condition is true). Default value: #[attributes.method == 'GET' or attributes.method == 'HEAD']

No

Conditional Response Caching Expression

The DataWeave expression that is used to decide which responses are to be cached (caches the response only if the condition is true). Default value: #[[200, 203, 204, 206, 300, 301, 404, 405, 410, 414, 501] contains attributes.statusCode]

No

How This Policy Works

When an HTTP request reaches an endpoint, what happens next depends on whether that request does not already exist in cache (a cache miss) or whether it does (a cache hit).

Cache Miss

In a cache miss scenario, the HTTP Caching policy checks whether a response to the submitted request is already cached. The request reaches the backend and the process is initiated only when it’s a cache miss. The diagram illustrates the flow of events that occur in this scenario:

http policy cache miss

  1. The client (user) sends a request to the API.

  2. The request proceeds through other policies in the policy chain before reaching the HTTP Caching policy.

  3. The HTTP Caching policy checks if the request is already in the object store and, if not, the cache miss process is initiated.

  4. The request continues throughout the chain of other remaining policies.

  5. The request reaches the backend and completes all required processing.

  6. The backend responds and the response travels back through the policy chain.

  7. The response reaches the HTTP Caching policy.

  8. Caching hits the object store again and attempts to save the key of the request for later reuse.

  9. The response continues through the remaining policies in the policy chain.

  10. The response is returned to the client.

Cache Hit

In a cache hit scenario, the HTTP Caching policy searches for the key in the object store and finds that the response to a request is already cached as a stored entry. The request does not proceed any further in the policy chain toward the backend, and the cached response is reused.

Subsequently, all the policies that must be executed in the policy chain after caching are not executed, in case of a cache hit:

http policy cache hit

  1. The client (user) sends a request to the API.

  2. The request crosses other policies before reaching the HTTP Caching policy.

  3. The HTTP Caching policy verifies that the request is already in the cache.

  4. The key is found in the object store and the stored response is returned.

  5. The response continues through the rest of the policy chain until it reaches the last one.

  6. The cached response is returned to the client.

Stored Entries

Stored entries are the cached HTTP responses. The cache can store any serializable data or input streams of up to 1 MB. If that value is surpassed, then the reading stops and the value is not stored in such a case.

HTTP Caching Key

The cache works as a dictionary, where each response stored in the cache is associated with a string called key. For example, the expression #[attributes.headers['key']] uses the header called key as the entry key. You can use any DataWeave expression that returns a string, including predefined DataWeave variables.

Cache Size and Entry Expiration

The cache can hold a specified number of entries at any given time. You can configure this number using the Maximum Cache Entries property. Each stored entry is held in the cache memory for a specific period of time, after which the entry expires and must be processed again. This expiration time is called time to live (TTL).

Another condition that can trigger the expiration of an entry is when the cache reaches the maximum number of items that it can store. When this scenario occurs, the entry is removed by using the FIFO (First-In First-Out) criteria. This means that the earliest entry to reach the cache is removed, even though it hasn’t reached the TTL value yet.

Distributed Cache

Each entry in the cache can be shared between different nodes in a cluster or between several workers in Runtime Manager using the Distributed option (see table). If this option is not enabled, then each node is assigned its own cache memory.

Persistent Cache

A persistent cache enables the stored entries in the cache to persist if the Flex Replica is restarted.

When you upgrade a version of the instance that has the HTTP Caching policy configured to use the persistent store, the policy tries to maintain the entries stored by the previous version. However in a worst-case scenario, the entries in the cache are invalidated and the cache is re-populated when new requests arrive. This manipulation of the entries in the cache occurs automatically and is invisible to the user.

HTTP Caching Directives

To obtain more control over the cache, the HTTP Caching policy interprets some of the HTTP directives from the RFC-7234 protocol by taking the following headers into account:

  • Cache-Control

  • Expires

  • Date

  • Age

Cache-Control

The Cache-Control header can exist either in the request or in the response. Possible values for the header, which can be combined separated by commas, include:

  • In requests:

    • no-cache

The response is not searched for, but is directly stored in the cache.

  • no-store

The response is not stored in the cache. However, if the response is already present in the cache, the policy returns the response.

  • In responses:

    • no-store, no-cache, private

For each value, the response is not stored in the cache.

  • max-age=<integer>, s-maxage=<integer>

The <integer> placeholder must be replaced with a valid integer that indicates the time (in seconds) for which the response can remain in the cache. If both parameters are defined, s-maxage takes precedence over max-age.

If a global time-to-live (TTL) value is also defined for the policy, these header values override the global TTL configured in the policy if the time specified in the headers is less than the global TTL.

Expires

If present, this header specifies the date by which the entry in the cache expires. If you specify the max-age directive or s-maxage directive, this header is ignored. You must define the header value as stated in RFC-1123.

Date

The date header, as defined per RFC-1123, specifies the date and time when the response is created. If not defined, the date header is added with the time when the request was received. This header is used in conjunction with the values defined in the max-age and s-maxage directives of the Cache-Control header.

Age

The age header indicates the time (in seconds) elapsed since the origin of the cached response specified in the date header. This header is calculated by the policy and added to each response that is retrieved from the cache.

The expiration time is calculated using the cache-control, date, and expires headers. However, if the resulting expiration time exceeds the one imposed by the TTL value of the entry, the cache entry expires anyway.

Invalidate

The invalidate header, if configured in the HTTP Caching policy, invalidates the entries in the cache, thereby causing the request to be processed again. You specify the name of the header in the Invalidation Header configuration to turn on the option. The value of the header can take only one of the following options: invalidate

This option invalidates the entry whose key matches the current request. invalidate-all This option invalidates all the entries from the cache.

For example, imagine that the following values are configured in the policy for the request:

  • HTTP Caching Key: "#[attributes.requestPath]"

  • Invalidation header: "myInvalidationHeader"

The following command invalidates the entry with key “/my/policy" from the cache:

curl http://<MyAppURL>/my/policy -H “myInvalidationHeader:invalidate”

The following request invalidates all entries from the cache:

curl http://<MyAppURL>/my/policy -H “myInvalidationHeader:invalidate-all”

Conditional Caching

Conditional caching enables you to configure a set of conditions that must be met before entries are stored in the cache. If none of the conditional caching parameters are configured, the cache stores the responses for every incoming request. If configured, parameters are evaluated for each request to determine whether the response of the current request must be stored.

For conditional request expressions, only the responses for incoming requests with HTTP methods GET or HEAD are cached by default. For conditional response expressions, only status codes specified by RFC-7231 are cached by default.

For more information about the default values, see Configuring Policy Parameters.

FAQ

What happens when the evaluation of the key results in any error?

If the evaluation of the expression for a particular request results in an error, the policy does not take effect and the request continues to the next receptor in the policy chain.

Can I store only part of the response with this policy?

No, but you can apply a policy before this one and transform the response to something else.

What happens if one parameter is configured to search for the response in the cache and the other parameter is configured for the opposite action?

This is the same as configuring the response to be stored in the cache when there is a no-store directive in the Cache-Control header.

In this situation, the response isn’t stored. You must configure both the Cache-Control header and the cache to be able to store and search for the response in the cache.

What happens if I do not define some of the optional parameters?

If you have not configured the invalidation header, you cannot invalidate the cache in a request. Additionally, if you have not configured the request expression or response expression, the cache is used for all requests and all the responses are stored in the cache (expression #[true]).

Can I modify the Invalidation header values?

No, you can modify only the header name.