Usando '304 Não Modificado' e 'If-Modified-Since' em uma API REST como uma estratégia de cache

5

Eu tenho o seguinte cenário: um aplicativo cliente que consome uma API REST. O cliente é um aplicativo móvel. Portanto, armazena em cache os dados da API para economia de largura de banda e suporte offline.

Com o REST, isso pode ser feito usando o cabeçalho If-Modified-Since . Ou seja, o sistema de gerenciamento de cache do lado do cliente armazena o HTTP-Date e o envia como um Cabeçalho dentro do pedido para a API, no qual, é feita uma verificação e acontece de enviar um status '304 Não Modificado' caso o recurso não foi modificado desde os dados especificados.

The "If-Modified-Since" header field makes a GET or HEAD request method conditional on the selected representation's modification date being more recent than the date provided in the field-value. Transfer of the selected representation's data is avoided if that data has not changed (rfc7232#section-3.3 If-Modified-Since).

Assumindo que, por "recursos", poderia ser uma coleção ou um único registro, a data modificada seria a data de modificação do recurso (ou seja, se for uma coleção de registros, a data seria toda a data da modificação da coleção ). Então, internamente, faria uma consulta ao banco de dados para verificar se o registro ou a coleção foi modificado desde então e produzir uma resposta adequada.

Até agora, é assim que pretendo implementar a estratégia de cache, tanto quanto possível.

O problema é que é uma decisão de design de alto impacto, e não tenho certeza se é uma boa abordagem ou se há uma maneira melhor de implementar isso. Toda a ideia é baseada em lógica e um pouco de conhecimento REST e não encontrei nenhum recurso sobre como implementar isso.

Eu gostaria de algumas críticas sobre este modelo, se é bom o suficiente, ter uma abordagem melhor ou até mesmo algumas ressalvas para melhorar a idéia atual, seria tudo apreciado.

    
por lenilsondc 12.07.2017 / 19:03
fonte

2 respostas

4

If-Modified-Since funciona bem para recursos únicos, onde é rápido e fácil determinar se o recurso foi modificado. Por exemplo, os servidores HTTP possuem essa funcionalidade integrada em arquivos estáticos, já que ela pode usar o registro de data e hora do arquivo. O conceito geral é que o processamento do recurso é mais caro do que determinar sua data de modificação. Eu consideraria isso para recursos únicos, mas não para coleções.

Existem vários esquemas de cache para escolher, e você deve usar apenas o mais apropriado para resolver a necessidade. Em alguns casos, o armazenamento em cache é prejudicial. Exemplos:

  • Os resultados são obrigados a alterar cada solicitação (ou seja, alta taxa de alteração)
  • Os proxies podem quebrar esquemas de armazenamento em cache que são específicos do usuário (por exemplo, um cenário de caixa de entrada)
  • O custo de determinar se o item é mais recente é o mesmo que recuperá-lo (ou seja, a diferença de tempo apenas para verificar uma data e obter um registro inteiro de um banco de dados é geralmente insignificante, mas fazendo duas consultas quando piora as coisas)

Eu fui mordido por um número de bugs de cache induzidos por proxy, particularmente servidores proxy antigos e não bem mantidos em redes de clientes. Teste com vários usuários para garantir que seus esforços de armazenamento em cache não piorem as coisas.

    
por 12.07.2017 / 21:30
fonte
2

A desvantagem da sua abordagem é que ela não cobre muitos dos cenários de armazenamento em cache. Cada elemento parece estar em cache para sempre (pelo menos por um tempo muito longo) e, quando o cliente fica sem memória, ele decide quais elementos em cache devem ser removidos, sem dar a você nenhum controle sobre o processo. Na vida real, você geralmente precisa ser capaz de ter esse tipo de controle, para, por exemplo, sair do cache os elementos que são raramente usados, enquanto mantém aqueles que são usados com muito mais frequência.

Se você não precisa desse tipo de controle, sua abordagem é perfeita.

Observe que, se para alguns recursos, você não tiver a data da última modificação, poderá usar HTTP ETags, por exemplo, calculando o hash do objeto no banco de dados e comparando-o ao hash fornecido pelo cliente .

    
por 12.07.2017 / 21:07
fonte

Tags