MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Jak zbudować skracacz adresów URL za pomocą Node.js i MongoDB

W tym poście pokażemy, jak zbudować usługę skracania adresów URL, taką jak bit.ly lub goo.gl, przy użyciu Express.js (Node.js) i MongoDB. Oto demonstracja końcowego produktu, który będziemy tworzyć za pośrednictwem naszej platformy hostingowej MongoDB.

Jak działa skracacz adresów URL?

Na bardzo wysokim poziomie narzędzie do skracania adresów URL działa, biorąc wprowadzony adres URL i tworząc stosunkowo skróconą wersję uproszczoną do formatu łatwego do udostępniania. Skrócony skrót zostanie wygenerowany przez zakodowanie bazowe licznika z automatycznym zwiększaniem i tworzy co najmniej trzyznakowy skrót, który rośnie wraz ze wzrostem liczby przechowywanych adresów URL.

Kiedy skrócona wersja adresu URL zostanie odwiedzona, usługa zdekoduje skrót, aby pobrać oryginalny adres URL przechowywany w MongoDB, a następnie przekieruje do niego użytkownika.

Pierwsze kroki

Oto lista technologii, których użyjemy do zbudowania skracacza adresów URL w tym samouczku:

  • Express.js (backend Node.js)

    Struktura aplikacji internetowych dla Node.js. Wykorzystamy go do zbudowania interfejsu API do skracania adresów URL i przekierowywania użytkowników do oryginalnego adresu URL.

  • MongoDB (przechowywanie adresów URL)

    Baza danych NoSQL idealna do tej aplikacji. Zapewnia elastyczny projekt schematu i jest łatwy do rozpoczęcia. W tym samouczku będziemy używać współdzielonego klastra MongoDB na ScaleGrid. Konfiguracja zajmuje mniej niż 5 minut, a na początek możesz utworzyć bezpłatny 30-dniowy okres próbny tutaj.

  • HTML, CSS, JavaScript (front-end)

    HTML, CSS i JavaScript zostaną użyte do zbudowania interfejsu aplikacji, którego użytkownicy będą używać do skracania adresów URL.

Jak zbudować skracacz adresów URL za pomocą Node.js i MongoDBCKliknij, aby tweetować

Samouczek skracania adresów URL

  1. Skonfiguruj strukturę bazy danych MongoDB

    Zacznijmy od utworzenia współdzielonego klastra MongoDB na ScaleGrid. Jest to najłatwiejszy sposób na utworzenie szybkiego klastra, ale możesz także zainstalować MongoDB na swoim komputerze i zacząć tam.

    Po utworzeniu klastra otrzymasz parametry połączenia, które można skopiować jednym kliknięciem na stronie Szczegóły klastra. Będziemy potrzebować tego ciągu, aby połączyć się z klastrem z naszej aplikacji. Pamiętaj, nigdy nie udostępniaj nikomu swoich parametrów połączenia.

    Będziemy potrzebować dwóch zbiorów do skracania adresów URL:

    • Kolekcja 1

      Zbiór do przechowywania adresu URL i dynamicznie generowanego identyfikatora:

    • Kolekcja 2

      Zbiór do obsługi licznika, który będzie automatycznie zwiększany, gdy nowy adres URL zostanie zapisany w poprzedniej kolekcji. Nowy dokument jest tworzony w poprzedniej kolekcji z tym nowo zwiększonym licznikiem:

    Ważne jest, aby pamiętać, że nie przechowujemy skrótów nigdzie w bazie danych. Skrót będzie kodowany w bazie i dekodowany dynamicznie za pomocą ogólnego algorytmu, którego wynikiem będzie unikalny identyfikator przechowywany w pierwszej kolekcji. Ten identyfikator spowoduje następnie pobranie oryginalnego adresu URL, do którego użytkownik przekieruje.

    W tym samouczku użyjemy wspólnego mechanizmu kodowania i dekodowania base64 do generowania naszego unikalnego skróconego skrótu. Aby uzyskać więcej informacji na temat kodowania/dekodowania ciągów znaków za pomocą base64, zapoznaj się z następującą dokumentacją sieciową MDN.

  2. Skonfiguruj zaplecze Express.js

    Oto lista zależności wymaganych do skonfigurowania naszego backendu Node.js:

    • ekspres (aplikacja podstawowa)
    • body-parser (dodatek do analizowania danych przesyłanych przez żądania HTTP)
    • btoa (kodowanie base64)
    • atob (dekodowanie base64)
    • dotenv (przechowywanie parametrów połączenia w pliku .env do celów programistycznych)
    • mangusta (adapter dla MongoDB na Node.js)

    Oto przykładowa wersja pliku package.json, której możesz użyć do skonfigurowania aplikacji:

    {
      "name": "sg-url-shortener",
      "version": "1.0.0",
      "description": "A simple URL shortener built with Node.js and 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"
      }
    }
    

    Uruchom „npm install”, aby zainstalować wszystkie wymagane zależności.

    Po skonfigurowaniu wszystkich naszych zależności musimy połączyć się z naszym współdzielonym klastrem MongoDB. Utwórz plik env w katalogu głównym projektu i dodaj do niego parametry połączenia. Parametry połączenia możesz pobrać ze strony Szczegóły klastra na karcie Przegląd w konsoli ScaleGrid.

    connectionString=mongodb://user:password@devservers

    Zanim zaczniemy pisać kod, dobrą praktyką jest wizualizacja przepływu aplikacji, dzięki czemu dobrze rozumiemy, jak będzie działać proces skracania. Oto diagram przedstawiający proces skracania adresu URL:

    Oto diagram pokazujący proces przekierowania po odwiedzeniu skróconego adresu URL:

    Teraz, gdy zwizualizowaliśmy cały proces, nadszedł czas, aby przetłumaczyć powyższe schematy blokowe na kod.

  3. Inicjowanie aplikacji

    Zanim zaczniemy pisać logikę biznesową, musimy zainicjować naszą aplikację z naszymi modułami węzłów i skonfigurować serwer.

    Załaduj pliki .env tylko w trybie deweloperskim. Ponieważ aplikacja demonstracyjna jest hostowana na Heroku, zmienna środowiskowa została utworzona z pulpitu nawigacyjnego Heroku, która już zawiera tam ciąg połączenia:

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

    Inicjowanie aplikacji, konfiguracja serwera i oprogramowania pośredniczącego. Zauważ, że otrzymujemy również ciąg połączenia ze zmiennej środowiskowej:

    var express = require('express'),
        bodyParser = require('body-parser'),
        app = express(),
        http = require('http').Server(app),
        mongoose = require('mongoose'),
        btoa = require('btoa'),
        atob = require('atob'),
        promise,
        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
    }));

    Podstawa do załadowania frontonu naszej aplikacji:

    app.get('/', function(req, res) {
        res.sendFile('views/index.html', {
            root: __dirname
        });
    });
    
  4. Przechowywanie adresów URL w MongoDB

    Zacznijmy od stworzenia schematów kolekcji do przechowywania danych. Jak omówiono powyżej, potrzebujemy dwóch kolekcji:jednej do przechowywania licznika autoinkrementacji, a drugiej do przechowywania adresów URL.

    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);
    

    Powyższy kod tworzy dwie kolekcje i konfiguruje naszą bazę danych do przechowywania tych kolekcji. Używamy również haka wstępnego zapisywania dla schematu adresu URL, ponieważ musimy automatycznie zwiększać licznik i rejestrować datę i godzinę utworzenia adresu URL.

    Następnie musimy upewnić się, że uruchamiamy naszą aplikację od nowa i wszystkie poprzednie wpisy zostały usunięte. Po zresetowaniu zainicjujemy nasz licznik z wartością początkową 10 000, aby skonfigurować proces skracania adresu URL. Możesz zacząć od dowolnej wartości. Zostało to wybrane losowo i automatycznie zwiększy się o wartość jeden.

    promise = mongoose.connect(connectionString, {
        useMongoClient: true
    });
    
    promise.then(function(db) {
        console.log('connected!');
        URL.remove({}, function() {
            console.log('URL collection removed');
        })
        Counter.remove({}, function() {
            console.log('Counter collection removed');
            var counter = new Counter({_id: 'url_count', count: 10000});
            counter.save(function(err) {
                if(err) return console.error(err);
                console.log('counter inserted');
            });
        });
    });
    

    Nasza aplikacja jest teraz gotowa do przyjmowania i skracania adresów URL! Stwórzmy POST API, którego nasz interfejs użyje do wysłania adresu 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('entry NOT found in db, saving new');
                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'
                    });
                });
            }
        });
    });

    Jak pokazano na schemacie blokowym, po otrzymaniu prawidłowego adresu URL sprawdzamy, czy istnieje w bazie danych.

    Jeśli zostanie znalezione, dekodujemy odpowiednie pole _id i zwracamy hash. Nasz front-end konstruuje skrócony adres URL i przedstawia go użytkownikowi w celu przekierowania.

    Jeśli nie zostanie znaleziony żaden adres URL, zapisujemy nowy dokument w kolekcji. Pamiętaj, że krok przed zapisaniem jest uruchamiany za każdym razem, gdy zapisywany jest adres URL. Spowoduje to automatyczne zwiększenie licznika i zapisanie bieżącej daty i godziny. Po dodaniu dokumentu wysyłamy skrót do naszego interfejsu, który konstruuje skrócony adres URL i przedstawia go użytkownikowi w celu przekierowania.

  5. Przekierowywanie użytkowników

    Prawie skończyliśmy! Po utworzeniu skróconych adresów URL potrzebujemy sposobu na przekierowanie użytkownika po odwiedzeniu skróconego adresu URL.

    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('/');
            }
        });
    });

    Powyższy kod szuka skrótu w skróconym adresie URL, dekoduje go base64, sprawdza, czy ten identyfikator jest obecny w kolekcji, i odpowiednio przekierowuje użytkownika. Jeśli nie zostanie znaleziony żaden identyfikator, użytkownik zostanie przekierowany na stronę główną skracacza adresów URL.

    W przypadku kodu front-end, sprawdź repozytorium GitHub wspomniane na końcu tego posta. Zasadniczo jest to pole tekstowe z przyciskiem do wysyłania adresu URL do zaplecza i wykracza poza zakres tego artykułu.

Więcej ulepszeń skracania adresów URL

I gotowe! Mamy proste narzędzie do skracania adresów URL, które można wykorzystać wewnętrznie, aby uprościć linki. Jeśli chcesz dodać więcej dzwonków i gwizdków, oto lista rzeczy, które możesz dodatkowo wdrożyć:

  • Lepsze dzielenie kodu
  • Lepszy/niestandardowy algorytm skracania dla mniejszego skrótu znaków (np. base52)
  • Udostępnianie skróconych adresów URL w mediach społecznościowych
  • Kopiowanie adresu URL jednym kliknięciem
  • Niestandardowe skróty
  • Rejestracja użytkownika i kojarzenie skróconych adresów URL

Cały kod jest dostępny tutaj: ScaleGrid URL Shortener Code Samples – Github Aplikacja demonstracyjna jest hostowana na Heroku:ScaleGrid URL Shortener Demo

Jak zawsze, jeśli tworzysz coś niesamowitego, napisz do nas o tym na Twitterze @scalegridio. Jeśli potrzebujesz pomocy w zakresie hostingu dla MongoDB® lub hostingu dla Redis™*, skontaktuj się z nami pod adresem [email protected].


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Błąd uwierzytelniania podczas próby zapisania w mongodb

  2. Atomowość, izolacja i współbieżność w MongoDB

  3. Połącz pełny tekst z innym indeksem

  4. Jak używać $elemMatch do projekcji agregatu?

  5. Nie znaleziono klasy „MongoDB\Driver\Manager”