Como configurar o cache do lado do servidor e a compactação da carga útil da API no AWS AppSync - AWS AppSync GraphQL

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Como configurar o cache do lado do servidor e a compactação da carga útil da API no AWS AppSync

AWS AppSyncOs recursos de cache de dados do lado do servidor disponibilizam os dados em um cache na memória de alta velocidade, melhorando a performance e diminuindo a latência. Isso reduz a necessidade de acessar fontes de dados diretamente. O armazenamento em cache está disponível para resolvedores unitários e de pipeline.

O AWS AppSync também permite compactar as respostas da API para que o conteúdo da carga seja carregado e baixado mais rapidamente. Isso reduz potencialmente a pressão sobre suas aplicações e, ao mesmo tempo, reduz potencialmente suas cobranças de transferência de dados. O comportamento de compactação pode ser configurado e definido a seu próprio critério.

Consulte esta seção se precisar de ajuda para definir o comportamento desejado do armazenamento em cache e da compactação do lado do servidor em sua API do AWS AppSync.

Tipos de instância

O AWS AppSync hospeda instâncias do Amazon ElastiCache (Redis OSS) na mesma conta da AWS e região da AWS que a sua API do AWS AppSync.

O tipos de instâncias do ElastiCache (Redis OSS) a seguir estão disponíveis:

pequeno

1 vCPU, 1,5 GiB de RAM, performance de rede moderada

medium

2 vCPU, 3 GiB de RAM, performance de rede moderada

grande

2 vCPUs, 12,3 GiB de RAM, performance de rede de até 10 Gigabit

xlarge

4 vCPU, 25,05 GiB de RAM, performance de rede de até 10 Gigabit

2xlarge

8 vCPU, 50,47 GiB de RAM, performance de rede de até 10 Gigabit

4xlarge

16 vCPU, 101,38 GiB de RAM, performance de rede de até 10 Gigabit

8xlarge

32 vCPU, 203,26 GiB de RAM, performance de rede de 10 Gigabit (não disponível em todas as regiões)

12xlarge

48 vCPU, 317,77 GiB de RAM, performance de rede de até 10 Gigabit

nota

Historicamente, você especificou um tipo de instância específico (como t2.medium). Em julho de 2020, esses tipos de instâncias legados ainda estavam disponíveis, mas seu uso está obsoleto e não é recomendado. Recomendamos que você use os tipos de instância genéricos descritos aqui.

Comportamento de armazenamento em cache

Veja a seguir os comportamentos relacionados ao armazenamento em cache:

Nenhum

Sem armazenamento em cache no lado do servidor.

Armazenamento em cache de solicitação completa

O armazenamento em cache de solicitações completo é um mecanismo que armazena em cache os resultados da execução do resolvedor individualmente. Com essa configuração, o AWS AppSync armazena em cache a execução de todos os resolvedores invocados durante uma solicitação, com cada resolvedor armazenado em cache separadamente. Os dados de cada resolvedor são recuperados pela fonte de dados e preencherão o cache até a vida útil (TTL) expirar. Para solicitações à API subsequentes, os resultados de cada resolvedor específico são retornados pelo cache. Isso significa que as fontes de dados não são contatadas diretamente, a menos que a TTL tenha expirado. O AWS AppSync usa o conteúdo dos mapas context.identity e context.arguments como chaves de armazenamento em cache para cada resolvedor.

Armazenamento em cache por resolvedor

Com essa configuração, cada resolvedor precisa ser aceito explicitamente para armazenar as respostas em cache. Um valor de TTL e as chaves de armazenamento em cache podem ser especificados no resolvedor. As chaves de cache que você pode especificar são os mapas context.arguments, context.source e context.identity de nível superior e/ou campos de strings desses mapas. O valor do TTL é obrigatório, mas as chaves de armazenamento em cache são opcionais. Se você não especificar nenhuma chave de cache, os padrões serão o conteúdo dos mapas context.arguments, context.source e context.identity.

Por exemplo, é possível usar as seguintes combinações:

  • context.arguments e context.source

  • context.arguments e context.identity.sub

  • context.arguments.id ou context.arguments.InputType.id

  • context.source.id e context.identity.sub

  • context.identity.claims.username

Quando você especifica somente um TTL e nenhuma chave de cache, o comportamento do resolvedor é o mesmo do cache completo da solicitação.

Armazenamento em cache no nível da operação

O armazenamento em cache no nível da operação armazena respostas inteiras da operação de consulta do GraphQL como um todo. Quando habilitado, as respostas de consulta bem-sucedidas são armazenadas em cache até que a TTL expire, com um tamanho máximo de resposta armazenável em cache de 15 MB. Para solicitações de consulta subsequentes com a mesma chave de cache, as respostas serão oferecidas diretamente pelo cache sem executar nenhum resolvedor enquanto o TTL não tiver expirado.

A chave de cache do armazenamento em cache no nível da operação é gerada usando uma combinação das seguintes opções:

  • Determinados atributos da carga útil JSON da solicitação:

    • A string query

    • A string operationName

    • O mapa variables

  • O mapa context.identity (exceto context.identity.sourceIp para solicitações do IAM e do Amazon Cognito)

  • O mapa context.request.headers (exceto determinados cabeçalhos reservados listados na próxima seção)

O tipo de autorização usado pela solicitação também afetará a chave de cache. Para solicitações autorizadas pelo IAM, a chave de cache também incluirá a lista de recursos permitidos e negados. Para solicitações autorizadas pelo Lambda, a chave de cache também incluirá a lista de campos negados.

A chave de cache vai considerar todos os cabeçalhos de solicitação encontrados em context.request.headers, exceto os seguintes cabeçalhos reservados, que normalmente são exclusivos de solicitações específicas:

  • authorization

  • cloudfront-forwarded-proto

  • cloudfront-is-desktop-viewer

  • cloudfront-is-mobile-viewer

  • cloudfront-is-smarttv-viewer

  • cloudfront-is-tablet-viewer

  • cloudfront-viewer-asn

  • cloudfront-viewer-country

  • content-length

  • host

  • priority

  • sec-ch-ua

  • sec-ch-ua-mobile

  • sec-ch-ua-platform

  • via

  • x-amz-cf-id

  • x-amz-date

  • x-amz-security-token

  • x-amzn-appsync-is-vpce-request

  • x-amzn-remote-ip

  • x-amzn-requestid

  • x-amzn-trace-id

  • x-forwarded-for

Vida útil do cache

Ele define por quanto tempo as entradas em cache ficarão armazenadas na memória. A TTL máxima é de 3.600 s (1 h), depois desse período as entradas serão automaticamente excluídas.

Criptografia de cache

Quando você usa o atributo de armazenamento em cache dos dados no lado do servidor do AWS AppSync, a criptografia em repouso e em trânsito permanece sempre habilitada para novos caches e não pode ser desabilitada.

Para habilitar a criptografia em um cache de API existente, exclua o cache e, em seguida, recrie-o.

Para invalidar as entradas de cache, você pode fazer uma chamada de API para limpar o cache usando o console do AWS AppSync ou a AWS Command Line Interface (AWS CLI).

Para obter mais informações, consulte o tipo de dados ApiCache na Referência de API do AWS AppSync.

Remoção de cache

Ao configurar o cache do lado do servidor do AWS AppSync, você pode configurar um TTL máximo. Ele define por quanto tempo as entradas em cache serão armazenadas na memória. Quando precisar remover entradas específicas do seu cache, você poderá usar o utilitário de evictFromApiCache extensões do AWS AppSync na solicitação ou resposta do seu resolvedor. (Por exemplo, os dados em suas fontes de dados mudaram, e agora sua entrada de cache ficou obsoleta.) Para remover um item do cache, você deve saber qual é sua chave. Por esse motivo, se você precisar despejar itens dinamicamente, recomendamos usar o cache por resolvedor e definir explicitamente uma chave para adicionar entradas ao seu cache.

Remover uma entrada de cache

Para remover um item do cache, use o utilitário de extensões evictFromApiCache. Especifique o nome do tipo e o nome do campo e, em seguida, forneça um objeto de itens de valor-chave para criar a chave da entrada que você deseja remover. No objeto, cada chave representa uma entrada válida do objeto context que é usada na lista de cachingKey em cache do resolvedor. Para criar o valor da chave são usados os valores reais. Você deve colocar os itens no objeto seguindo a ordem das chaves de cache na lista em cache de cachingKey do resolvedor.

Por exemplo, confira o seguinte esquema:

type Note { id: ID! title: String content: String! } type Query { getNote(id: ID!): Note } type Mutation { updateNote(id: ID!, content: String!): Note }

Neste exemplo, você pode habilitar o armazenamento em cache por resolvedor e, em seguida, habilitá-lo para a consulta de getNote. Em seguida, é possível configurar a chave de cache de modo que ela seja [context.arguments.id].

Quando você tenta obter uma Note para criar a chave de cache, o AWS AppSync executa uma busca em seu cache do lado do servidor usando o argumento do id da consulta de getNote.

Ao atualizar uma Note, é preciso remover a entrada da nota específica para garantir que a próxima solicitação realize a busca na fonte de dados do back-end. Para isso, crie um manipulador de solicitações.

O exemplo a seguir mostra um modo de lidar com a remoção usando este método:

import { util, Context } from '@aws-appsync/utils'; import { update } from '@aws-appsync/utils/dynamodb'; export function request(ctx) { extensions.evictFromApiCache('Query', 'getNote', { 'ctx.args.id': ctx.args.id }); return update({ key: { id: ctx.args.id }, update: { context: ctx.args.content } }); } export const response = (ctx) => ctx.result;

Outra opção é tratar da remoção no manipulador de respostas.

Quando a mutação de updateNote é processada, o AWS AppSync tenta remover a entrada. Se uma entrada for apagada com sucesso, a resposta vai conter um valor de apiCacheEntriesDeleted no objeto extensions que mostra quantas entradas foram excluídas:

"extensions": { "apiCacheEntriesDeleted": 1}

Remover uma entrada de cache com base na identidade

Você pode criar chaves de cache com base em diversos valores do objeto context.

Por exemplo, veja o esquema a seguir, que usa grupos de usuários do Amazon Cognito como modo de autenticação padrão e é apoiado por uma fonte de dados do Amazon DynamoDB:

type Note { id: ID! # a slug; e.g.: "my-first-note-on-graphql" title: String content: String! } type Query { getNote(id: ID!): Note } type Mutation { updateNote(id: ID!, content: String!): Note }

Os tipos de objeto Note são salvos em uma tabela do DynamoDB. A tabela tem uma chave composta que usa o nome de usuário do Amazon Cognito como chave primária e o id (um slug) da Note como chave de partição. Esse é um sistema multilocatário que pode hospedar vários usuários e atualizar seus objetos privados Note, que nunca são compartilhados.

Como esse é um sistema que exige muita leitura, a getNote consulta é armazenada usando o cache por resolvedor, com a chave de cache composta por [context.identity.username, context.arguments.id]. Quando a Note é atualizada, você pode despejar a entrada específica da Note. Você deve adicionar os componentes no objeto seguindo a ordem em que estão especificados na lista de cachingKeys do seu resolvedor.

O exemplo a seguir mostra isso.

import { util, Context } from '@aws-appsync/utils'; import { update } from '@aws-appsync/utils/dynamodb'; export function request(ctx) { extensions.evictFromApiCache('Query', 'getNote', { 'ctx.identity.username': ctx.identity.username, 'ctx.args.id': ctx.args.id, }); return update({ key: { id: ctx.args.id }, update: { context: ctx.args.content } }); } export const response = (ctx) => ctx.result;

Um sistema de back-end também pode atualizar a Note e remover a entrada. Por exemplo, considere esta mutação:

type Mutation { updateNoteFromBackend(id: ID!, content: String!, username: ID!): Note @aws_iam }

Você pode despejar a entrada, mas adicionar os componentes da chave de cache ao objeto cachingKeys.

No exemplo a seguir, a remoção ocorre na resposta do resolvedor:

import { util, Context } from '@aws-appsync/utils'; import { update } from '@aws-appsync/utils/dynamodb'; export function request(ctx) { return update({ key: { id: ctx.args.id }, update: { context: ctx.args.content } }); } export function response(ctx) { extensions.evictFromApiCache('Query', 'getNote', { 'ctx.identity.username': ctx.args.username, 'ctx.args.id': ctx.args.id, }); return ctx.result; }

Nos casos em que seus dados de back-end tiverem sido atualizados fora do AWS AppSync, você pode remover um item do cache chamando uma mutação que usa uma fonte de dados NONE.

Compactar respostas da API

O AWS AppSync permite que os clientes solicitem cargas compactadas. Se solicitadas, as respostas da API são compactadas e retornadas em resposta às solicitações que indicam que o conteúdo compactado tem preferência. As respostas compactadas da API carregam mais rápido, assim como o download do conteúdo, e suas taxas de transferência de dados também podem ser reduzidas.

nota

A compactação está disponível em todas as novas APIs criadas depois de 1º de junho de 2020.

O AWS AppSync compacta objetos na base do melhor esforço. Em casos raros, o AWS AppSync pode pular a compactação com base em vários fatores, incluindo a capacidade atual.

O AWS AppSync pode compactar tamanhos de payload da consulta do GraphQL entre 1.000 a 10.000.000 bytes. Para ativar a compactação, o cliente deve enviar o cabeçalho de Accept-Encoding com o valor gzip. A compactação pode ser confirmada ao verificar o valor do cabeçalho Content-Encoding na resposta (gzip).

O explorador de consultas no console do AWS AppSync define automaticamente o valor do cabeçalho na solicitação por padrão. Se você executar uma consulta com uma resposta grande o suficiente, a compactação poderá ser confirmada usando as ferramentas de desenvolvedor do seu navegador.