MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Como construir um encurtador de URL com Node.js e MongoDB

Nesta postagem, mostraremos como criar um serviço de encurtamento de URL como bit.ly ou goo.gl usando Express.js (Node.js) e MongoDB. Aqui está uma demonstração do produto final que construiremos por meio de nossa plataforma de hospedagem MongoDB.


Como funciona um encurtador de URL?

Em um nível muito alto, o encurtador de URL funciona pegando um URL inserido e criando uma versão relativamente abreviada simplificada em um formato fácil de compartilhar. O hash encurtado será gerado pela codificação de base de um contador incrementado automaticamente e cria um hash mínimo de três caracteres que aumenta à medida que o número de URLs armazenados aumenta.

Quando a versão abreviada da URL for visitada, o serviço decodificará o hash para buscar a URL original armazenada no MongoDB e redirecionar seu usuário para ela.

Primeiros passos

Aqui está uma lista das tecnologias que usaremos para criar o encurtador de URL neste tutorial:

  • Express.js (back-end Node.js)

    Uma estrutura de aplicativo da Web para Node.js. Vamos usá-lo para construir uma API para encurtar URLs e redirecionar os usuários para a URL original.

  • MongoDB (armazenando URLs)

    Um banco de dados NoSQL perfeito para este aplicativo. Ele fornece um design de esquema flexível e é fácil de começar. Neste tutorial, usaremos um cluster MongoDB compartilhado no ScaleGrid. A configuração leva menos de 5 minutos, e você pode criar uma avaliação gratuita de 30 dias aqui para começar.

  • HTML, CSS, JavaScript (front-end)

    HTML, CSS e JavaScript serão usados ​​para criar o front-end do aplicativo que seus usuários usarão para encurtar URLs.

Como construir um encurtador de URL com Node.js e MongoDBClick To Tweet

Tutorial do encurtador de URL

  1. Configurar a estrutura do banco de dados MongoDB

    Vamos começar criando um cluster MongoDB compartilhado no ScaleGrid. Essa é a maneira mais fácil de criar um cluster rápido, mas você também pode instalar o MongoDB em sua máquina e começar lá.


    Depois que o cluster for criado, você receberá uma string de conexão que pode ser copiada com um único clique na página de detalhes do cluster. Precisaremos dessa string para conectar ao cluster de nosso aplicativo. Lembre-se, nunca compartilhe sua string de conexão com ninguém.

    Vamos precisar de duas coleções para o encurtador de URL:

    • Coleção 1

      Uma coleção para armazenar o URL e o ID gerado dinamicamente:

    • Coleção 2

      Uma coleção para manter o contador que será incrementado automaticamente quando uma nova URL for armazenada na coleção anterior. Um novo documento é criado na coleção anterior com este contador recém-incrementado:

    É importante observar que não estamos armazenando os hashes em nenhum lugar do banco de dados. O hash será codificado em base e decodificado dinamicamente com o algoritmo geral que resultará no ID exclusivo armazenado na primeira coleção. Esse ID irá buscar a URL original para a qual o usuário irá redirecionar.

    Para este tutorial, usaremos o mecanismo comum de codificação e decodificação base64 para gerar nosso hash abreviado exclusivo. Para obter mais informações sobre codificação/decodificação de strings usando base64, consulte o seguinte MDN Web Doc.

  2. Configurar o back-end Express.js

    Aqui está uma lista de dependências necessárias para configurar nosso back-end Node.js:

    • expresso (aplicativo básico)
    • body-parser (complemento para analisar dados enviados por solicitações HTTP)
    • btoa (codificação base64)
    • atob (decodificação base64)
    • dotenv (armazenando string de conexão em um arquivo .env para fins de desenvolvimento)
    • mongoose (adaptador para MongoDB no Node.js)

    Aqui está uma versão de amostra do package.json que você pode usar para configurar o aplicativo:

    { "name":"sg-url-shortener", "version":"1.0.0", "description":"Um encurtador de URL simples criado com Node.js e MongoDB", "dependencies":{ " atob":"^2.0.3", "body-parser":"^1.15.2", "btoa":"^1.1.2", "dotenv":"^4.0.0", "express":" ^4.10.2", "mangusto":"^4.13.7" }, "main":"index.js", "scripts":{ "start":"node index.js" }, "engines":{ "nó":"4.8.4" }}

    Execute “npm install” para instalar todas as dependências necessárias.

    Depois que todas as nossas dependências estiverem configuradas, precisamos nos conectar ao nosso cluster MongoDB compartilhado. Crie um arquivo .env na raiz do projeto e adicione a cadeia de conexão a ele. Você pode obter a string de conexão na página "Detalhes do cluster" na guia "Visão geral" no Console do ScaleGrid.

    connectionString=mongodb://user:password@devservers

    Antes de começarmos a escrever o código, é uma boa prática visualizar o fluxo do aplicativo para que tenhamos uma boa compreensão de como o processo de redução funcionará. Aqui está um diagrama que mostra o processo de encurtamento de URL:


    Aqui está um diagrama mostrando o processo de redirecionamento quando um URL encurtado é visitado:


    Agora que visualizamos todo o processo, é hora de traduzir os fluxogramas acima em código.

  3. Inicializando o aplicativo

    Antes de começarmos a escrever a lógica de negócios, precisamos inicializar nosso aplicativo com nossos módulos de nó e configurar um servidor.

    Carregar arquivos .env somente no modo dev. Como o aplicativo de demonstração está hospedado no Heroku, uma variável de ambiente foi criada no painel do Heroku que já contém a string de conexão lá:

    if(process.env.NODE_ENV !=='production') { require('dotenv').load();}

    Inicialização de aplicativos, configuração de servidor e middleware. Observe que também estamos obtendo a string de conexão da variável de ambiente:

    var express =require('express'), bodyParser =require('body-parser'), app =express(), http =require('http').Server(app), mongoose =require('mongoose '), btoa =require('btoa'), atob =require('atob'), promessa, connectionString =process.env.connectionString, port =process.env.PORT || 8080;http.listen(port, function() { console.log('Server Started. Listening on *:' + port);});app.use(express.static('public'));app.use( bodyParser.urlencoded({ extended:true}));

    Rota base para carregar o front-end do nosso aplicativo:

    app.get('/', function(req, res) { res.sendFile('views/index.html', { root:__dirname });});
  4. Armazenando URLs no MongoDB

    Vamos começar criando os esquemas de coleta para armazenar dados. Conforme discutido acima, precisamos de duas coleções:uma para armazenar o contador incrementado automaticamente e outra para armazenar as URLs.

    var countersSchema =new mongoose.Schema({ _id:{ type:String, required:true }, count:{ type:Number, default:0 }});var Counter =mongoose.model('Counter', countersSchema );var urlSchema =new mongoose.Schema({ _id:{type:Number}, url:'', created_at:''});urlSchema.pre('save', function(next) { console.log('running pre-save'); var doc =this; Counter.findByIdAndUpdate({ _id:'url_count' }, { $inc:{ count:1 } }, function(err, counter) { if(err) return next(err); console.log(counter); console.log(counter.count); doc._id =counter.count; doc.created_at =new Date(); console.log(doc); next(); });});var URL =mongoose.model('URL', urlSchema);

    O código acima cria as duas coleções e configura nosso banco de dados para armazenar essas coleções. Também estamos usando um gancho de pré-salvamento para o esquema de URL, pois precisamos incrementar automaticamente o contador e registrar a data e hora em que a URL foi criada.

    Em seguida, precisamos ter certeza de que iniciamos nosso aplicativo de novo e todas as entradas anteriores foram excluídas. Depois de redefinir, inicializaremos nosso contador com um valor inicial de 10.000 para configurar o processo de encurtamento de URL. Você pode começar com qualquer valor. Isso foi escolhido aleatoriamente e será incrementado automaticamente por um valor de um.

    promise =mongoose.connect(connectionString, { useMongoClient:true});promise.then(function(db) { console.log('connected!'); URL.remove({}, function() { console. log('coleção de URL removida'); }) Counter.remove({}, function() { console.log('Counter collection removida'); var counter =new Counter({_id:'url_count', count:10000} ); counter.save(function(err) { if(err) return console.error(err); console.log('contador inserido'); }); });});

    Nosso aplicativo agora está pronto para começar a aceitar e encurtar URLs! Vamos criar uma API POST que nosso front-end usará para enviar a URL:

    app.post('/shorten', function(req, res, next) { console.log(req.body.url); var urlData =req.body.url; URL.findOne({url:urlData} , function(err, doc) { if(doc) { console.log('entry found in db'); res.send({ url:urlData, hash:btoa(doc._id), status:200, statusTxt:' OK' }); } else { console.log('entrada NÃO encontrada no banco de dados, salvando novo'); var url =new URL({ url:urlData }); url.save(function(err) { if(err) return console.error(err); res.send({ url:urlData, hash:btoa(url._id), status:200, statusTxt:'OK' }); }); } });}); 

    Conforme descrito no diagrama de fluxo, quando um URL válido é recebido, verificamos sua existência no banco de dados.

    Se encontrado, decodificamos o campo _id correspondente e retornamos o hash. Nosso front-end constrói o URL encurtado e o apresenta ao usuário para redirecionamento.

    Se nenhuma URL for encontrada, salvamos um novo documento na coleção. Lembre-se, uma etapa de pré-salvamento é executada toda vez que a URL é salva. Isso incrementará automaticamente o contador e registrará a data e hora atuais. Depois que o documento é adicionado, enviamos o hash para nosso front-end, que constrói a URL abreviada e a apresenta ao usuário para redirecionamento.

  5. Redirecionando usuários

    Estamos quase terminando! Depois que nossos URLs encurtados forem criados, precisamos de uma maneira de redirecionar o usuário quando um URL encurtado for visitado.

    app.get('/:hash', function(req, res) { var baseid =req.params.hash; var id =atob(baseid); URL.findOne({ _id:id }, function(err , doc) { if(doc) { res.redirect(doc.url); } else { res.redirect('/'); } });});

    O código acima procura um hash na URL abreviada, a base64 o decodifica, verifica se esse ID está presente na coleção e redireciona o usuário de acordo. Se nenhum ID for encontrado, o usuário será redirecionado para a página inicial do encurtador de URL.

    Para código front-end, confira o repositório GitHub mencionado no final deste post. É essencialmente um campo de caixa de texto com um botão para enviar a URL para o back-end e está fora do escopo deste artigo.

Mais aprimoramentos do encurtador de URL

E pronto! Temos um encurtador de URL básico que pode ser usado internamente para simplificar seus links. Se você quiser adicionar mais sinos e assobios, aqui está uma lista de coisas que você pode implementar adicionalmente:

  • Melhor divisão de código
  • Algoritmo de encurtamento melhor/personalizado para um hash de caractere menor (por exemplo, base52)
  • Compartilhamento de URLs abreviados nas mídias sociais
  • Cópia de URL com um clique
  • Hastes personalizados
  • Registro do usuário e URLs abreviados associados

O código inteiro está disponível aqui: Amostras de código do ScaleGrid URL Shortener – Github Um aplicativo de demonstração está hospedado no Heroku:ScaleGrid URL Shortener Demo

Como sempre, se você criar algo incrível, envie-nos um tweet sobre isso @scalegridio. Se você precisar de ajuda com hospedagem para MongoDB® ou hospedagem para Redis™*, entre em contato conosco em [email protected].