On a hit the cached response is replayed and the handler chain is not
invoked. On a miss the handler runs and its response is stored in the
background through ICloudflareBindings.waitUntil, so the write never delays
the client.
Skipped without error, each reported as X-Cache-Api: BYPASS or MISS:
the request is not a GET — the key is a URL string the Cache API resolves
as a GET, so a POST could otherwise be answered from a cached GET;
bypass returned true;
with the default key, the URL is not in its parsed form, carries a
fragment, or a tenant id or locale is not well-formed, or the request
lacks a tenant or locale while its URL contains setu-cache-tenant= or
setu-cache-locale= — in each case no key could keep the request apart
from another (this last one applies to an application without either
plugin too);
no cache handle is available (not running on Cloudflare Workers);
the response is a live stream — teeing it would double the memory the
stream exists to avoid and change its flush timing (the M42 guard
cache-plugin also applies);
assessCacheability found a refusal, so put would have thrown.
Two platform properties are worth knowing before relying on this:
caches.default is per-datacenter, so it is a latency optimisation and
not a shared store; and it is scoped to the zone, so a key must be unique
across every route that caches.
One testing note: a HIT is replayed with IResponse.stream, so a cached
response of any size reaches the client without being buffered — which means
app.inject() cannot read its body. Drive a cached route with app.fetch
and a web Request, which is what a Worker invokes anyway.
Caches responses in the Cloudflare edge cache.
On a hit the cached response is replayed and the handler chain is not invoked. On a miss the handler runs and its response is stored in the background through
ICloudflareBindings.waitUntil, so the write never delays the client.Skipped without error, each reported as
X-Cache-Api: BYPASSorMISS:GET— the key is a URL string the Cache API resolves as a GET, so aPOSTcould otherwise be answered from a cachedGET;bypassreturnedtrue;setu-cache-tenant=orsetu-cache-locale=— in each case no key could keep the request apart from another (this last one applies to an application without either plugin too);cache-pluginalso applies);assessCacheabilityfound a refusal, soputwould have thrown.Two platform properties are worth knowing before relying on this:
caches.defaultis per-datacenter, so it is a latency optimisation and not a shared store; and it is scoped to the zone, so a key must be unique across every route that caches.One testing note: a HIT is replayed with
IResponse.stream, so a cached response of any size reaches the client without being buffered — which meansapp.inject()cannot read its body. Drive a cached route withapp.fetchand a webRequest, which is what a Worker invokes anyway.