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.
[cc lang=”javascript”]
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}”`));
}
};
function randomString(length, chars) {
var result = ”;
for (var i = length; i > 0; –i) result += chars[Math.floor(Math.random() * chars.length)];
return result;
}
[/cc]
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!”