I dette indlæg viser vi dig, hvordan du opbygger en URL-forkortelsestjeneste som bit.ly eller goo.gl ved hjælp af Express.js (Node.js) og MongoDB. Her er en demo af det endelige produkt, vi skal bygge gennem vores MongoDB-hostingplatform.
Hvordan virker en URL Shortener?
På et meget højt niveau fungerer URL-forkorteren ved at tage en indtastet URL og skabe en relativt forkortet version forenklet til et format, der er let at dele. Den forkortede hash vil blive genereret ved at base-indkode en auto-inkrementeret tæller, og skaber en minimum tre-tegn hash, der stiger i takt med at antallet af lagrede URL'er stiger.
Når den forkortede version af URL'en besøges, vil tjenesten afkode hashen for at hente den originale URL, der er gemt i MongoDB og derefter omdirigere din bruger til den.
Kom godt i gang
Her er en liste over de teknologier, vi vil bruge til at bygge URL-forkorteren i denne øvelse:
-
Express.js (Node.js-backend)
En webapplikationsramme til Node.js. Vi bruger den til at bygge en API til at forkorte URL'er og omdirigere brugere til den originale URL.
-
MongoDB (lagring af webadresser)
En NoSQL-database perfekt til denne applikation. Det giver et fleksibelt skemadesign og er nemt at komme i gang med. I denne tutorial bruger vi en delt MongoDB-klynge på ScaleGrid. Det tager mindre end 5 minutter at konfigurere, og du kan oprette en gratis 30-dages prøveperiode her for at komme i gang.
-
HTML, CSS, JavaScript (front-end)
HTML, CSS og JavaScript vil blive brugt til at bygge den frontend af applikationen, som dine brugere vil bruge til at forkorte webadresser.
URL Shortener Tutorial
-
Konfigurer MongoDB-databasestrukturen
Lad os starte med at oprette en delt MongoDB-klynge på ScaleGrid. Dette er den nemmeste måde at oprette en hurtig klynge på, men du kan også installere MongoDB på din maskine og komme i gang der.
Når klyngen er oprettet, vil du blive forsynet med en forbindelsesstreng, der kan kopieres med et enkelt klik fra siden med klyngedetaljer. Vi skal bruge denne streng for at oprette forbindelse til klyngen fra vores applikation. Husk, del aldrig din forbindelsesstreng med nogen.
Vi skal bruge to samlinger til URL-forkorteren:
-
Samling 1
En samling til at gemme URL'en og dynamisk genereret ID:
-
Samling 2
En samling til at vedligeholde tælleren, der automatisk øges, når en ny URL er gemt i den forrige samling. Et nyt dokument oprettes i den tidligere samling med denne nye tæller:
Det er vigtigt at bemærke, at vi ikke gemmer hasherne nogen steder i databasen. Hashen vil blive base-kodet og afkodet dynamisk med den generelle algoritme, der vil resultere i det unikke ID, der er gemt i den første samling. Dette ID vil derefter hente os den originale URL, som brugeren vil omdirigere til.
Til denne øvelse bruger vi den almindelige base64-kodnings- og afkodningsmekanisme til at generere vores unikke forkortede hash. For mere information om kodning/afkodning af strenge ved hjælp af base64, se vores følgende MDN Web Doc.
-
-
Konfigurer Express.js Backend
Her er en liste over afhængigheder, der kræves for at konfigurere vores Node.js-backend:
- express (basisapp)
- body-parser (tilføjelse til at parse data sendt via HTTP-anmodninger)
- btoa (base64-kodning)
- atob (base64-afkodning)
- dotenv (lagring af forbindelsesstreng i en .env-fil til udviklingsformål)
- mongoose (adapter til MongoDB på Node.js)
Her er en eksempelversion af package.json, som du kan bruge til at konfigurere appen:
{ "name":"sg-url-shortener", "version":"1.0.0", "description":"En simpel URL-forkorter bygget med Node.js og MongoDB", "dependencies":{ " atob":"^2.0.3", "body-parser":"^1.15.2", "btoa":"^1.1.2", "dotenv":"^4.0.0", "express":" ^4.10.2", "mongoose":"^4.13.7" }, "main":"index.js", "scripts":{ "start":"node index.js" }, "engines":{ "node":"4.8.4" }}
Kør "npm install" for at installere alle de nødvendige afhængigheder.
Når alle vores afhængigheder er blevet sat op, skal vi oprette forbindelse til vores delte MongoDB-klynge. Opret en .env-fil i projektets rod, og tilføj forbindelsesstrengen til den. Du kan hente forbindelsesstrengen fra siden med klyngedetaljer under fanen Oversigt på ScaleGrid-konsollen.
connectionString=mongodb://user:password@devservers
Før vi begynder at skrive kode, er det en god praksis at visualisere appflowet, så vi har en god forståelse af, hvordan afkortningsprocessen vil fungere. Her er et diagram, der viser processen med URL-forkortelse:
Her er et diagram, der viser processen med omdirigering, når en forkortet URL besøges:
Nu hvor vi har visualiseret hele processen, er det tid til at oversætte ovenstående flowcharts til kode.
-
Initialisering af applikationen
Før vi begynder at skrive forretningslogik, skal vi initialisere vores applikation med vores nodemoduler og konfigurere en server.
Indlæs kun .env-filer i udviklertilstand. Da demoapplikationen er hostet på Heroku, er der oprettet en miljøvariabel fra Heroku-dashboardet, der allerede indeholder forbindelsesstrengen der:
if(process.env.NODE_ENV !=='produktion') { require('dotenv').load();}
Initialisering af applikation, server- og middleware-opsætning. Bemærk, at vi også får forbindelsesstrengen fra miljøvariablen:
var express =require('express'), bodyParser =require('body-parser'), app =express(), http =require('http').Server(app), mongoose =require('mongoose '), btoa =require('btoa'), atob =require('atob'), løfte, forbindelsesstreng =process.env.connectionString, port =process.env.PORT || 8080;http.listen(port, function() { console.log('Server startede. Listening on *:' + port);});app.use(express.static('public'));app.use( bodyParser.urlencoded({ extended:true}));
Basisrute til indlæsning af front-end af vores app:
app.get('/', function(req, res) { res.sendFile('views/index.html', { root:__dirname });});
-
Lagring af URL'er i MongoDB
Lad os starte med at oprette indsamlingsskemaerne til lagring af data. Som diskuteret ovenfor har vi brug for to samlinger:en til lagring af den automatiske tæller og den anden til lagring af webadresser.
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 =dette; 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);
Ovenstående kode opretter de to samlinger og sætter vores database op til lagring af disse samlinger. Vi bruger også en pre-save hook til URL-skemaet, da vi skal automatisk øge tælleren og logge datoen og klokkeslættet, hvor URL'en blev oprettet.
Dernæst skal vi sikre os, at vi starter vores applikation på en frisk, og at alle tidligere poster slettes. Når vi har nulstillet, initialiserer vi vores tæller med en startværdi på 10.000 for at konfigurere URL-forkortningsprocessen. Du kan starte med enhver værdi. Dette blev valgt tilfældigt og vil automatisk øges med en værdi på én.
promise =mongoose.connect(connectionString, { useMongoClient:true});promise.then(function(db) { console.log('connected!'); URL.remove({}, function() { console. log('URL-samling fjernet'); }) Counter.remove({}, function() { console.log('Tællersamling fjernet'); var counter =new Counter({_id:'url_count', count:10000} ); counter.save(function(err) { if(err) return console.error(err); console.log('tæller indsat'); }); });});
Vores applikation er nu klar til at begynde at acceptere og forkorte URL'er! Lad os oprette en POST API, som vores frontend vil bruge til at sende URL'en:
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('indgang fundet i db'); res.send({ url:urlData, hash:btoa(doc._id), status:200, statusTxt:' OK' }); } else { console.log('indgang IKKE fundet i db, gemmer ny'); var url =ny URL({ url:urlData }); url.save(funktion(err) { if(err) return console.error(err); res.send({ url:urlData, hash:btoa(url._id), status:200, statusTxt:'OK' }); }); } });});
Som skitseret i flowdiagrammet, så kontrollerer vi, når en gyldig webadresse er modtaget, for dens eksistens i databasen.
Hvis fundet, afkoder vi det tilsvarende _id-felt og returnerer hashen. Vores frontend konstruerer den forkortede URL og præsenterer den for brugeren til omdirigering.
Hvis ingen URL findes, gemmer vi et nyt dokument i samlingen. Husk, at der køres et forudgående trin, hver gang URL'en gemmes. Dette vil automatisk øge tælleren og logge den aktuelle dato og klokkeslæt. Efter at dokumentet er tilføjet, sender vi hashen til vores frontend, som konstruerer den forkortede URL og præsenterer den for brugeren til omdirigering.
-
Omdirigere brugere
Vi er næsten færdige! Når vores forkortede URL'er er blevet oprettet, har vi brug for en måde at omdirigere brugeren på, når en forkortet URL besøges.
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('/'); } });});
Ovenstående kode søger efter en hash i den forkortede URL, base64 afkoder den, tjekker om dette ID er til stede i samlingen og omdirigerer brugeren i overensstemmelse hermed. Hvis der ikke findes noget ID, omdirigeres brugeren til hjemmesiden for URL-forkorteren.
For frontend-kode, tjek venligst GitHub-depotet nævnt i slutningen af dette indlæg. Det er i bund og grund et tekstfelt med en knap til at sende URL'en til back-end og er uden for denne artikels omfang.
Flere URL Shortener-forbedringer
Og vi er færdige! Vi har en bare-bones URL-forkorter, der kan bruges internt til at forenkle dine links. Hvis du gerne vil tilføje flere klokker og fløjter, er her en liste over ting, du yderligere kan implementere:
- Bedre kodeopdeling
- Bedre/tilpasset forkortningsalgoritme for en mindre karakterhash (f.eks. base52)
- Deling af forkortede webadresser på sociale medier
- Et-klik URL-kopi
- Tilpassede hashes
- Brugerregistrering og tilknyttede forkortede URL'er
Hele koden er tilgængelig her: ScaleGrid URL Shortener Code Samples – Github En demoapplikation er hostet på Heroku:ScaleGrid URL Shortener Demo
Som altid, hvis du bygger noget fantastisk, så tweet os om det @scalegridio. Hvis du har brug for hjælp til hosting for MongoDB® eller hosting for Redis™*, kan du kontakte os på [email protected].