This topic discusses Apigee Edge support for HTTP/1.1 response caching headers and directives.

About HTTP/1.1 response caching

The HTTP/1.1 specification describes standard caching headers and control mechanisms that support caching along the HTTP request/response chain. These headers and mechanisms provide information about cached resources and help servers determine how to manage cached data. You can refer to the spec itself for detailed information about caching in HTTP, and there are also many blogs, articles, and other resources available on the Internet that explain HTTP caching.

The focus of this topic is to explain how Apigee Edge processes and handles HTTP/1.1 headers related to response caching.

Apigee Edge currently supports a subset of the HTTP/1.1 caching headers and directives. Where appropriate, we'll point out features that are not supported.

Caching in Apigee Edge

Apigee Edge provides a persistence layer that allows HTTP responses and arbitrary variables to be stored in caches. You enable and control this persistence layer with policies. Edge provides policies for storing arbitrary variables (the Cache policies) and a policy for controlling HTTP response caching (the ResponseCache policy).

You can read an overview of the Edge persistence layer in Persistence.

Edge does not perform any caching unless one or more of these policies are attached to a proxy.

This topic concerns HTTP response caching and how the HTTP/1.1 caching headers are handled when the ResponseCache policy is employed by a proxy. To learn about adding and configuring the ResponseCache policy, see Response Cache policy.

Enabling HTTP/1.1 response caching in Apigee Edge

When the ResponseCache policy is added to a proxy, HTTP responses are cached and retrieved according to how the proxy is configured. The ResponseCache policy includes two flag elements that, when set, allow the policy to consider HTTP cache headers. If you want to use these HTTP cache header features, you need to set these flag elements. They are:

  • UseResponseCacheHeaders: If set to true, the HTTP response headers are used when setting the "time to live" (TTL) of the response in the cache. The Expires response header is ignored by default unless this flag is set to true. If the max-age or s-maxage directives of the Cache-Control header are set, they take precedence over the Expires header value.
  • UseAcceptHeader: When this flag is set to true, the Accept headers in the response are used to generate a cache key. The default is false. See "How are cache keys generated". 

In addition, Edge looks for and evaluates certain HTTP caching headers. Edge also considers these headers and takes appropriate action based on their directives. In some cases, these HTTP/1.1 cache headers override whatever behavior is specified in the ResponseCache policy. For example, if the Cache-Control header is returned from a backend server, the header's  s-maxage directive  directives overrides the corresponding setting in the ResponseCache policy.

Edge supports the following HTTP cache headers on responses received from backend target (origin) servers:

On client GET requests, Edge supports the If-Modified-Since header.

Edge also supports Entity Tags (ETags) and their related GET request headers. 

Finally, Edge provides support for caching and returning compressed responses.

The Cache-Control response header

This section discusses Apigee Edge support for the Cache-Control header.

Although the HTTP/1.1 spec allows Cache-Control headers in both client requests and origin server responses, Apigee Edge only supports the Cache-Control header on responses returned from origin servers (backend targets). Origin servers can include both target endpoints defined in an Apigee Edge API proxy and those created using TargetServer API calls.

When Apigee Edge detects a Cache-Control response header, it looks at the header's directives and takes appropriate processing steps. 

About Cache-Control header support

Apigee Edge supports a subset of Cache-Control response header capabilities defined in the HTTP/1.1 specification. Please note the following:

  • Apigee Edge does not support Cache-Control headers that arrive with inbound client requests.  
  • According to the HTTP specification, Cache-Control can either be public (shared) or private (single user). However, Apigee Edge only supports the notion of public caches.   
  • Not all Cache-Control response directives in the HTTP/1.1 specification are supported by Edge. See "Support for Cache-Control response header directives" below for details.

Support for Cache-Control response header directives

The following table describes Apigee Edge support for HTTP Cache-Control response header directives.

Apigee supports a subset directives from the HTTP/1.1 specification on responses from origin servers . For more detailed information on these directives, see "Cache-Control" in the HTTP/1.1 specification.

Cache-Control directive  How Apigee Edge processes the directive
public Edge caches the origin response, even when other directives indicate otherwise. Per the HTTP/1.1 specification, the only exception to this rule is if the response includes an Authorization header. 
private This directive is not supported by Apigee Edge. If this directive is received, the origin response is not cached. Any field names are ignored. 
no-cache

Edge caches the origin response, but it must be revalidated with the origin server before being used to satisfy any subsequent client requests. This rule allows the origin to return a 304 Not Modified response in order to indicate that the response should be returned from cache, thus saving the processing required to return the entire response. If the origin server returns a full response, it replaces the existing cache entry. Any field names specified with this directive are ignored.

Note: The HTTP/1.0 header, Pragma: no-cache is treated as equivalent to Cache-Control: no-cache.
no-store Not supported. 
no-transform Not supported.
must-revalidate Not supported. All cache entries are deleted by Apigee Edge as soon as they expire. 
proxy-revalidate Not supported. All cache entries are deleted by Apigee Edge as soon as they expire. 
max-age

The response is cached for the specified number of seconds.

Note: This directive overrides any expiration specified in the Expires header and the ResponseCache policy. See also Response Cache policy.

s-maxage

The response is cached for the specified number of seconds. 

Note: This directive overrides any expiration specified in the Expires header and the ResponseCache policy. See also Response Cache policy.

cache-extension Not supported.

The Expires response header

Edge uses the Expires header on origin server responses to determine the time to live (TTL) of a cached entry. As expected, this header specifies a date/time after which a response's cache entry is considered stale. This header allows servers to signal when it's okay to return a cached value based on a time stamp. 

When the UseResponseCacheHeaders flag in the ResponseCache policy is set to true, the Cache-Control directives max-age and s-maxage take precedence over and override the behavior of the Expires header. 

Acceptable date formats for the Expires header are described in the HTTP/1.1 specification. For example:

Expires: Thu, 01 Dec 1994 16:00:00 GMT

For detailed information on HTTP date/time formats, see "Date/Time Formats" in the HTTP/1.1 specification.

While section 14.21 of the specification indicates that an Expires value of more than one year in the future means that a cache entry never expires, Apigee interprets such a value to mean that the entry should be cached until the specified date and time.

For more information on Expires header, see "Header Field Definitions" in the HTTP/1.1 specification. 

Entity Tag support 

An entity tag (ETag) is an identifier associated with a requested resource. This identifier allows servers to determine if the requested resource and the associated cached resource match or not. Servers can then take appropriate actions, such as re-caching a response if it does not match or returning the cached resource if the ETags match. When a target endpoint sends a response back to Edge with an ETag, Edge caches the ETag along with the response. You can read more about Entity Tags in "Protocol Parameters" in the HTTP/1.1 specification. 

If-Match request header support

The If-Match request header allows Edge to determine if a cached entity is current or not based on if the ETag in the header matches the ETag that is cached with the requested entity. You can read more about If-Match in "Header Field Definitions" in the HTTP/1.1 specification.

If Edge receives an inbound GET request from a client that includes an If-Match header:

  • If the If-Match header specifies one or more ETags, Apigee Edge retrieves any unexpired cached entries for the specified resource and compares any strong ETags on those cached entries with those specified in the If-Match header. If a match is found, the cached entry is returned. If not, the request is passed to the origin server.  
     
  • If the If-Match header specifies "*", the request is passed on to the origin server to ensure that any origin caching facilities have a chance to process the request.  
     
  • Any requests other than GET that specify an If-Match header are passed on to the origin server to ensure that any origin caching facilities have a chance to process the request.  
     
  • If a cache entry with the same request URI is found, but it contains only weak ETags, then the entry must be revalidated by the origin server before being returned to the client.   
     
  • Any ETags returned by the origin server are returned unchanged to the client. 

If-None-Match request header support

The If-None-Match header allows Edge to determine if a cached entity is current or not based on if the ETag in the header does not match the ETag that is cached with the requested entity.

If Edge receives an inbound GET request from a client that includes an If-None-Match header:

  • If the If-None-Match header specifies one or more ETags, Apigee Edge retrieves any unexpired cache entries for the specified URI and compares any strong ETags on those cached entries with those specified in the If-None-Match header. If a match is found, Edge returns a 304 Not Modified status. If no match is found, Edge passes the request to the origin server.  
     
  • If the If-None-Match header specifies "*" and an unexpired cached entry for the requested URI exists, Edge returns a 304 Not Modified status.  
     
  • Requests other than a GET that include an If-None-Match header are passed on to the origin server.  
     
  • If a cache entry with the same request URI is found but contains only weak ETags, then the entry must be revalidated by the origin server before Edge returns it to the client. 
     
  • If Edge receives an ETag from an origin server, the ETag is always returned unchanged to the client.

The If-Modified-Since header

If Apigee Edge receives an If-Modified-Since header in a GET request, it is passed along to the origin server even if a valid cache entry exists. This ensures that any updates to a resource that did not pass through Apigee Edge are accounted for. If the origin server returns a new entity, then Edge replaces the existing cache entry with the new value. If the server returns a 304 Not Modified status, Edge returns the response value if the cached response's Last-Modified header indicates that it has not changed.

Handling Compressed and uncompressed data

When a incoming request includes the header Accept-Encoding with values of gzip, deflate or compress, the origin server responds with compressed data. When subsequent responses come without the Accept-Encoding headers, they expect an uncompressed response. Apigee's response caching mechanism is capable of sending both compressed and uncompressed responses depending on the incoming headers without going back to the origin server.

How are cache keys generated?

When the ResponseCache flag UseAcceptHeader is set to true, Edge uses the Accept, Accept-Encoding, Accept-Language and Accept-Charset request headers when calculating the cache key. This approach prevents a client from getting a media type they did not ask for. For example, consider if two requests come in from the same URL, where the first request accepts gzip and the second does not. The first request will be cached, and the cached entry will (probably) be a gzipped response. The second request will read the cached value and may then return a gzipped entry to a client that is not capable of reading gzip. 

Which response codes are cached?

By default, Apigee Edge only caches 2xx level responses. Non-2xx responses are not cached. 

Help or comments?

  • Something's not working: See Apigee Support
  • Something's wrong with the docs: Click Send Feedback in the lower right.
    (Incorrect? Unclear? Broken link? Typo?)