Cache

Caching

A técnica de caching consiste em armazenar dados temporariamente em um componente mais eficiente para agilizar o acesso a informações. Assim, cada vez que um dado é solicitado e está presente no cache, a latência para sua disponibilização é extremamente reduzida.

Em situações de alta demanda, com um volume grande de requisições, a utilização do cache traz ganhos substanciais em termos de performance. O API Manager implementa a funcionalidade de caching para qualquer operação de uma API..

Como gerar e apagar cache?

O controle de uso de cache na resposta às requisições às APIs é feito por interceptores.

Para criar cache e utilizá-lo nas chamadas, é necessário usar uma dupla de interceptores: o Cache Write é usado para criar o cache e o Cache Read é usado para retornar respostas a partir do cache que foi criado. Já para apagar o cache, é necessário utilizar o interceptor Cache Invalidation.

Vamos entender o funcionamento parte por parte.

Em primeiro lugar, é importante ter em mente que o cacheamento de respostas é manipulado a nível de operação. Então, se você estiver editando o fluxo de uma API e não encontrar os interceptores de cache, cheque o campo Operations, acima da visualização do fluxo. Se você tiver selecionado a opção "All", os interceptors de cache não serão exibidos. Nesse caso, selecione uma operação específica para ver os interceptores e, se desejar, arrastá-los para o fluxo.

Para cachear uma resposta, o interceptor Cache Write deve ser inserido no fluxo de resposta de uma operação. Se a requisição for bem-sucedida, o Manager criará um cache com base nas configurações informadas. Para que o sistema utilize a resposta armazenada em memória, é necessário incluir o interceptor Cache Read no fluxo de requisição da operação. Note que o "Cache Name" configurado deve ser o mesmo em ambos os interceptores.

Para apagar a resposta armazenada em memória, insira o interceptor Cache Invalidation no fluxo de requisição ou resposta de uma operação, com o mesmo "Cache Name" configurado nos interceptores Cache Write e Cache Read.

Para limpar o cache todo (bem como controlar o volume de cache), vá até Settings  Cache Control (a página só aparece se seu usuário tiver permissão de "Cache Control" — por padrão, só para Super Admins). Veja mais sobre o controle de cache aqui.

Em casos onde a resposta da chamada é tratada por um Custom Interceptor, é necessário usar um outro Custom Interceptor para interromper o fluxo quando o Cache Read está populado. Isso evita que ocorra erro de tratamento no cache. O interceptor que interromperá o fluxo deve ser inserido em qualquer posição após o interceptor de Cache Read.

Cache Write e Cache Read

cache flow

O interceptor Cache Write, ao ser inserido no fluxo de resposta de uma determinada operação , irá criar um cache com base nas configurações informadas. A partir da segunda requisição, o sistema irá utilizar a resposta armazenada em memória. Para isso, basta adicionar um interceptor Cache Read no fluxo da operação:

Na configuração do caching, podem ser incluídos atributos do cabeçalho e/ou da URL para determinar unicamente a entrada de cache que deve ser utilizada. Além, é claro, do tempo de expiração do dado armazenado em cache.

cache write

O interceptor Cache Read é responsável por identificar um cache criado com base no cache name informado. Quando uma requisição é enviada para uma operação "cacheada", o interceptor identifica o cache e insere a resposta em memória na chamada. Isso traz ganho de performance, já que a requisição não precisará ser enviada para o backend.

cache read
O nome do cache deve ser o mesmo configurado no interceptor Cache Write.

Cache Invalidation

O interceptor Cache Invalidation é responsável por invalidar um determinado cache do sistema , com base no cache name informado. Ao ser inserido em uma determinada operação, o sistema irá localizar e excluir o cache.

cache invalidation

Cache key

As respostas a partir do cache não precisam ser sempre as mesmas, mas podem variar de acordo com elementos pré-definidos. A chave do cache (Cache key) identifica unicamente as respostas armazenadas. Todos os elementos da requisição (URL, headers, query params, etc) que influenciam a resposta precisam fazer parte da chave. Os elementos que não influenciam a resposta podem ser deixados de fora da chave.

A URL é sempre parte da chave.
  • Se a resposta a uma requisição pode ser reusada globalmente — como uma lista de cidades — então a URL já basta como chave. Isto significa que, depois do primeiro acesso a, por exemplo, GET /cities, todos os demais acessos, mesmo que por outras apps ou usuários, receberão a mesma resposta vinda do cache.

  • Se a URL é a mesma, mas a resposta é diferente dependendo do usuário ou app usados (por exemplo, GET /preferences retorna dados diferentes dependendo do usuário envolvido na chamada), então esse usuário/app precisa fazer parte da chave.

  • Outras informações que influenciam a resposta, como query params usados para filtro (ex: GET /products?orderBy=date vs. GET /products?orderBy=price) também precisam fazer parte da chave.

  • Parâmetros de paginação também são candidatos a fazerem parte da chave (ex: GET /products?page=1 vs. GET /products?page=2).

Para informar como a chave do cache deve ser formada, é preciso preencher dois campos após inserir o interceptor Cache Write no fluxo de resposta:

cache key
  • Headers to include in cache key: Insere uma lista separada por vírgulas de nomes de headers HTTP que devem ser usados para compor a chave.

  • Por exemplo, o valor client_id, access_token faz com que os headers client_id e access_token sejam usados para fazer parte da chave.

  • Query-params to include in cache key: Insere uma lista separada por vírgulas de nomes de query-params que devem ser usados para compor a chave.

Sub-recursos

Ao buscar no cache por respostas já existentes, o Gateway considerará apenas URLs que sejam exatamente iguais à requisitada. Isso significa que uma regra que configura o cache do recurso /products não configura o cache do recurso /products/{id}; de fato, do ponto de vista da API, os dois são recursos completamente distintos.

Observe, porém, que se for criada uma regra de cacheamento para o recurso /products/{id}, então o Gateway colocará no cache respostas diferentes para /products/123 e /products/456, como é o esperado. Isso significa que produtos populares serão servidos frequentemente a partir do cache, enquanto produtos menos vistos não estarão no cache e serão encaminhados diretamente ao backend.

As regras acima sobre headers e query params que fazem parte do cache também são levadas em conta para recursos, como /products/{id}.

Time-To-Live

Cada regra de cache especifica uma duração de tempo em que o cache é considerado válido. Depois desse tempo, as respostas no cache são descartadas. Observe que os valores são em segundos; tipicamente, um cache de respostas de API pode durar de alguns segundos a algumas horas, não mais do que isso.

Tamanho máximo

Internamente, o gateway possui um limite prático para a quantidade de bytes que ele pode armazenar em memória. O objetivo disso é proteger a infraestrutura do próprio gateway, para que uma resposta demasiadamente grande não ocupe a memória por muito tempo. Em geral, esse limite é grande o bastante para acomodar muitas chamadas de tamanho razoável. Entretanto, se o limite for atingido, novas respostas não serão armazenadas até que algumas sejam removidas.

Atualização de cache

A atualização do cache acontece quando o time-to-live expira e é realizado uma requisição para uma operação que possui os interceptores Cache Write e Cache Read no fluxo. Para invalidar um cache, basta inserir em uma operação um interceptor Cache Invalidation com o mesmo cache name.

Thanks for your feedback!
EDIT

Share your suggestions with us!
Click here and then [+ Submit idea]