flexway
FRENTalk to an expert

Caching a read

GuideOperationsSince version 1.2.0

Markdown

Operations guide: configure, deploy and observe the gateway. What the capability does, product side: product guide; calling it: developer guide.

Goal: serve a stable read (a catalogue, reference data) without a round trip to the upstream - without ever serving one caller what was answered to another.

Command - in the contract, on the operation:

paths:
  /products:
    get:
      x-flexway-cache: { ttl: 60s }                   # public: anonymous callers
  /me/cart:
    get:
      security: [ { customers: [] } ]
      x-flexway-cache: { ttl: 30s, scope: subject }   # one entry per tenant and subject

or, for a set of routes, a cache policy - always public:

policies:
  definitions:
    catalog-cache: { type: cache, config: { ttl: 5m } }
  chains:
    routes: { "/products/**": [catalog-cache] }

Check: the second request answers Flexway-Cache: hit and an Age, and the upstream never sees it; flexway_cache_lookups_total{result="hit"} goes up; /config shows cache in the catalogue, the console a "cached" mark. An If-None-Match matching the stored ETag gets a 304 from the cache.

Rule What it means
Nothing by default An operation without x-flexway-cache or a cache policy is never cached; the operation wins over the policy
The upstream shortens Lifetime = the shortest of ttl and max-age, s-maxage or Expires; no-store, no-cache, private, Set-Cookie: never kept
Known length A response without Content-Length is a stream to the gateway: relayed unbuffered, never kept
A hit counts Rate and quota are counted before the cache is read: it spares the upstream, never the caller's allowance
Identity An identified caller neither reads nor fills a public cache; an authenticated cache is declared by the operation (scope: subject), keyed by tenant and subject
Refused at load A cache on a stream, a WebSocket, a gRPC method, inference, a write; a public one on an operation that requires an identity - the message names the operation
Memory Per replica, bounded: server.cache.max_bytes (32 MiB), server.cache.max_entry_bytes (1 MiB); not reloadable; a reload purges it

Full example: Response cache.

Next steps