No artigo sobre AWS experience, onde desenvolvemos nosso encurtador de URL, ficou faltando uma etapa onde seria necessário expurgar as URLs curtas depois de N dias.
Uma das soluções propostas, seria desenvolver um job que diariamente obteria os registros da tabela onde a data de expiração fosse inferior ou igual a data corrente. Isso poderia ser feito utilizando o mesmo recurso que utilizamos em nosso artigo, porem existe uma forma mais fácil.
DynamoDB TTL
Existe um recurso no dynamoDB chamado TTL (Time to Live). Ao ativa-lo, você deve escolher uma das suas colunas/atributos da tabela, para que o campo seja tratado como TTL, este campo deve receber uma data no formato epoch. Após a ativação, o dynamoDB vai excluir automaticamente os registros cuja data corrente for superior ao valor informado no atributo TTL.
Caso você defina a expiração para 5 dias, ao atingir a data, o registro será excluído em até 48 horas. Nem todo requisito de software pode ser atendido com este delay, mas tratando-se de expurgo, é um cenário na maioria das vezes aceitável.
Setup
Acesse o banco de dados do dynamoDB e a sua tabela. Caso você tenha feito o artigo do encurtador de url, pode utilizar a mesma tabela que criamos, urlshort.
Nas definições da tabela, existe a opção Manage TTL em Time to Live Attribute. Clique nesta opção.
em TTL attribute, informe o nome do atributo/coluna da tabela que deve armazenar a data de expiração do registro, em nosso caso, este campo tem o nome expirationDate.
Marque também o checkbox dynamoDB Streams se você utiliza esse tipo de recurso. Quando habilitado, o streams permite enviar eventos sobre manipulações de registro com “antes” e “depois” da modificação.
Clique em continue e a configuração do recurso já está funcionando.
Data no formato Epoch
Caso você tenha duvida sobre o formato que deve ser usado ao gravar a data de expiração, deve ser utilizado o formato epoch. Este formato é um valor numérico correspondente ao número de segundos passados desde 0:00 do dia 01/01/1970. Segue uma referencia rápida de como obter esse valor em algumas linguagens.
Linux Terminal: date +%s
Python: import time; long(time.time())
Java: System.currentTimeMillis() / 1000L
JavaScript: Math.floor(Date.now() / 1000)
conversor de data para o formato epoch:
https://www.epochconverter.com
AWS Lambda
Sobre o artigo do encurtador de URL, vamos precisar modificar o nosso código lambda pra registrar a data de expiração, mas antes disso vamos configurar uma variável de ambiente no lambda, que será o total de dias que devemos somar a data corrente, para termos a nossa data de expiração.
Acesse a função lambda url-shrink e deixe selecionada a primeira camada.
descendo a barra de rolagem, inclua uma variável de ambiente chamada expirationDays e atribua o numero de dias que deseja, para o nosso caso, usamos 7.
Agora modifique o código da função para registrar no campo expirationDate da tabela urlshort, a data corrente + o valor da variável de ambiente expirationDays. Lembrando que a data deve ser salva no campo no formato epoch.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | console.log('Loading function'); const doc = require('dynamodb-doc'); const dynamo = new doc.DynamoDB(); exports.handler = (event, context, callback) => { //console.log('Received event:', JSON.stringify(event, null, 2)); //console.log('Received context:', context); var codepath = null; var numberOfDaysExpiration = 7; var bodyRetorno = null; const done = (err, res) => callback(null, { statusCode: err ? '400' : '200', body: err ? err.message : JSON.stringify(bodyRetorno), headers: { 'Content-Type': 'application/json', }, }); switch (event.httpMethod) { case 'DELETE': dynamo.deleteItem(JSON.parse(event.body), done); break; case 'GET': console.log("codepath", event.pathParams.codepath) var params = { TableName: "urlshort", Key:{ "codepath": event.pathParams.codepath } }; dynamo.getItem(params, function(err, data) { if (err) { console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2)); context.done(err, {}); } else { console.log("GetItem succeeded:", JSON.stringify(data, null, 2)); var dbObject = JSON.stringify(data, null, 2); console.log("URL to Redirect:", data.Item.originalURL); var err = new Error("HandlerDemo.ResponseFound Redirection: Resource found elsewhere"); err.name = data.Item.originalURL; context.done(err, {}); } }); break; case 'POST': //gerando o codigo da URL temporaria codepath = randomString(6, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'); //gerando a data de expiração var diasExpiracao = process.env.expirationDays; console.log("dias para expiração da url curta: " , diasExpiracao) var dataExpiracao = new Date(); dataExpiracao.setDate(dataExpiracao.getDate() + parseInt(diasExpiracao)); console.log("data de expiração do registro", dataExpiracao); var expirationDate = Math.floor(dataExpiracao / 1000) console.log("expirationDate" , expirationDate); var parsedJson = JSON.parse(event.body); console.log('expirationDate:', expirationDate); console.log('codepath:', codepath); parsedJson.Item.expirationDate = expirationDate; parsedJson.Item.codepath = codepath; bodyRetorno = { "codepath": codepath, }; dynamo.putItem(parsedJson, done); break; default: done(new Error(`Unsupported method "${event.httpMethod}"`));</code> } }; function randomString(length, chars) { var result = ''; for (var i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)]; return result; } |
O código acima é o código completo do artigo encurtador de url, atualizado com a gravação da expiração utilizando o TTL do dynamoDB. Veja no banco como registro foi salvo:
O valor 1546280536 referente ao campo expirationDate do primeiro registro, corresponde a data de 31 de dezembro as 18:22 sem aplicar o UTC e horario de verão
Pronto, o dynamoDB fez quase tudo pra você, o único incomodo é que agora quando você registrar a sua URL curta, você receberá uma ligação da amazon falando”Seven Days!”
Seja o primeiro a comentar