How I created a simple URL shortener using Node, Mongo and React.

How I created a simple URL shortener using Node, Mongo and React.

URL Shorteners are very useful if you want to remember a large URL of some websites. They trim down the huge URLs into really small URLs which are easier to remember and share. Here will be creating one using React and Node.

How does it work?

  1. You enter your long lengthy URL in the input field and the slug that you want to have in your trimmed URL on the website and hit submit.
  2. As soon as you hit submit, the backend logic fires a POST request which makes an entry in the database of the URL. Also, at the same time, if you have not entered a custom slug for your URL, it generates a random id consisting of 6 digits. This id is mapped with the long URL and stored in the database. Otherwise, a database query first checks that the slug you entered is not present in the database. (Necessary because the slug needs to be unique) If it is present, it notifies you to enter a new slug.
  3. After this step, the URL along with the slug or the random ID is stored in the database.

The following Code shows the backend logic which handles the requests coming from the frontend.

// This route finds all the shortURLs that have been created till now and displays them in a tabular form
app.get("/api", (req, res) => {
    ShortURLs.find(function(err,urls){
        if(err){
            console.log(err);
        }
        else{
            console.log(urls);
            res.json(urls);
        }
    });
});
app.post("/api/shortURLs", function (req, res) {
  let slug = req.body.slug;
  if (slug === '') { // If slug is not entered, generate random ID
      console.log(slug);
    slug = shortID.generate();
  }
  ShortURLs.find({ short: req.body.slug }, (err, docs) => {
    if (docs.length > 0) {
      res.sendStatus(500);// If slug is already present, notify user to enter new slug
    } else {
      ShortURLs.create({ full: req.body.fullURL, short: slug })
        .then(() => console.log("Short URL created!"))
        .catch((err) => console.log(err));
      res.redirect("/");
    }
  });
});
// This route finds a specific url associated with a particular id (:shortUrl)
// and the redirects to the long url associated with it
app.get("/api/:shortUrl", async (req, res) => {
    const shortUrl = await ShortURLs.findOne({ short: req.params.shortUrl });
    if (shortUrl == null) return res.sendStatus(404);
    shortUrl.clicks++;
    shortUrl.save();
    res.redirect(shortUrl.full);
});

Why use Mongo, Node and React

  • Node.js along with its Express framework helps in creating routes quickly without worrying. Also, Node.js provides a lot of packages which help to create the application fast by focusing on the meat of the application and leave the unimportant things.
  • MongoDB as the database is super easy to use and deploy. Also since we do not need to do complex queries, there is no harm in using NoSQL database.
  • Finally using React helps us to greatly reduce the loading time as it only re-renders the components whose state changes.

Further tasks

Ideally, URL Shorteners are huge systems and are a good question in System design interviews. So what all things can we do to improve our current system:

  • Use Redis /other caching database. Accessing the main database for each GET request is not efficient. So we can use some caching algorithms such as LRU or FIFO and based on that we can put data in Redis which is a caching database. So before accessing the main database, the system queries the cache database. If the data is not found in the cache, then only the main database is queried.
  • As it is possible a lot many people can access that site and make GET requests. So in such a case, we may need to implement a load balancer too.
  • Also, we can have the user create an account and display only those short URLs that he has created. This would enforce security. An implementation for this would be to give each user that visits the site a UUID. And store this UUID in his local storage. Then we can map all the URLs created by a particular UUID in the database and display only those URLs.

Feel free to contribute to this project if you want to.

Link to the project: github.com/inflame07/url-shrinker