Cache

Declarando um cache

Um único recurso de cache por aplicação — a rota nunca precisa apontar para qual, só usa cache:.

spec:
  caches:
    - { id: redis-main, provider: redis, connectionString: "${config:Redis}", failOpen: true }

provider: redis é a implementação de referência. Outro provider pode ser adicionado por um pacote de terceiro — veja ICacheProvider.

Duas formas de usar cache

Cache-aside manual, com os steps cache.*

- { type: cache.get, id: cached, cache: redis-main, key: "'order:' & input.route.orderId" }
- type: cache.set
  cache: redis-main
  key: "'order:' & vars.order.id"
  value: vars.order
  ttl: 5m
  tags: [orders]
- { type: cache.invalidate, cache: redis-main, tag: orders }
Step Função
cache.get Lê uma chave e publica em steps.<id>.resultnull numa falta (inclusive numa falta por fail-open, veja abaixo)
cache.set Grava uma chave com o(s) TTL(s) e tags informados
cache.invalidate Remove por chave (uma expressão JSONata) ou por tag (uma string literal) — exatamente um dos dois

cache.set aceita TTL absoluto (ttl) e/ou TTL deslizante (slidingTtl, que reseta a cada acerto) — os dois são opcionais e podem ser combinados. tags permite invalidar um grupo inteiro de chaves de uma vez com cache.invalidate.

Cache de resposta inteira, na própria rota

- id: getOrder
  method: GET
  path: /orders/{orderId}
  cache:
    key: "'order:' & input.route.orderId"
    ttl: 5m
    tags: [orders]
    bypassWhen: "input.headers.'cache-control' = 'no-cache'"
  pipeline:
    - ...
  response: { status: 200, body: "vars.order" }

O bloco cache: de uma rota faz cache-aside da resposta inteira, com proteção contra stampede (várias requisições concorrentes numa mesma chave ausente não disparam o pipeline inteiro em paralelo — apenas uma reconstrói o valor, as demais aguardam). bypassWhen é uma expressão opcional que, quando verdadeira, ignora o cache para aquela requisição específica.

Use os dois mecanismos deliberadamente: cache manual (cache.*) quando você quer cachear só uma parte do que a rota calcula (por exemplo, um valor auxiliar consultado no meio do pipeline); cache de rota quando a resposta inteira pode ser servida do cache sem rodar o pipeline de novo.

Comportamento fail-open

Um cache declarado com failOpen: true não derruba a requisição se o backend de cache estiver indisponível — uma falta é tratada como cache miss, o pipeline segue normalmente (recalculando o valor, se for o caso), e a indisponibilidade fica só nos logs/métricas. Isso é o comportamento recomendado para cache: cache é uma otimização, não deveria ser um novo ponto único de falha.

Para onde ir daqui