DEV Community

Cover image for How to make a URL shortner.
prajyu
prajyu

Posted on

How to make a URL shortner.

In this project you will learn how to build an API using express.js, how to connect it to a backend and how to handle http requests

fork or clone this repository for reference

NPM packages used

  • dependencies
cors
crc
express
mongodb
url
Enter fullscreen mode Exit fullscreen mode

  • dev dependencies ( npm i ${package_name}--save-dev )
dotenv
nodemon
Enter fullscreen mode Exit fullscreen mode

Initialize project

Initialize an npm project npm init -y and create api.js file

Build the Server

  
Install and import dependencies

  1. Install all the dependencies given above. dev depedencies is optional.

      - nodemon is used to automatically update the server file aka api.js
      - dotenv is used to load environment variables into the file
  
2. Import dependencies into api.js

const express = require("express");
const cors = require("cors");
const { crc32 } = require("crc");
const { MongoClient } = require("mongodb");
const { URL } = require("url");
Enter fullscreen mode Exit fullscreen mode


** Start the server **

1. Make the express app instance using this line of code

const app = express();
Enter fullscreen mode Exit fullscreen mode


2. Make the server able to recieve json files on POST requests

app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());
Enter fullscreen mode Exit fullscreen mode


3. Enable CORS on the server. This helps you in controlling access to the server from different addresses more about it here

app.use(cors());
Enter fullscreen mode Exit fullscreen mode


4. Make the server listen on a port

app.listen(process.env.PORT || 3030); 
Enter fullscreen mode Exit fullscreen mode

process.env.PORT helps in deployment

Now you have a working server 🎉🎉. But it doesn't do anything right now. So lets fix that...

Connect your server to mongoDB

If you don't know how to get started mongodb locally. Here's a link to get you started

  • We use npm package monodb to connect to database
const dbName = "dbName";

let collection = null // Global Variable

let main = async () => {
  let url = "mongodb://localhost:27017";
  const client = new MongoClient(url);
  await client.connect();
  const db = client.db(dbName);
  collection = db.collection("urls");
  const deleteResult = await collection.deleteMany({});
  // deletes all entry after each restart
};
Enter fullscreen mode Exit fullscreen mode

And call the function main()

Now your server is connected to your databse.

Link Shortner Function

We are going to be using CRC32 hash algorithm to shrink the URLS. This is where crc package comes into play.

let createUrl = (url) => {
  let shortenedUrl = crc32(url).toString(16);
  return shortenedUrl;
};
Enter fullscreen mode Exit fullscreen mode

This function reduces your URL to a 8 character string.

Create and Read from database

We are going to be making a collection with a pair like

{
  url:'original URL,
  shortenedUrl:'shrinked URL of the absolute URL
}

  • Add the URL to databse
let addUrl = async (url, shortenedUrl) => {
  const insertResult = await collection.insertOne({ shortenedUrl, url });
  return insertResult;
};
Enter fullscreen mode Exit fullscreen mode

  • Find pair from databse
let findUrl = async (shortenedUrl) => {
  const findResult = await collection.find({ shortenedUrl }).toArray();
  return findResult;
};
Enter fullscreen mode Exit fullscreen mode

Add routes to your API

  • Shrink URL

To shrink URL's we need to create a POST request in api.js

app.post("/shrink", async (req, res) => {
  ...
});
Enter fullscreen mode Exit fullscreen mode

After we defined the route. We need to process the incoming requests.

Get the URL from the body of the post request and shrink it using our earlier function.

let { url } = req.body;
let shortenedUrl = createUrl(url);
Enter fullscreen mode Exit fullscreen mode


Next we check if the shortenedUrl is already in our database using findUrl() function. If we get a hit we return the shortenedUrl or move to next part.

let result = await findUrl(shortenedUrl);
if (result.length >= 1) return res.json({ shortenedUrl });
Enter fullscreen mode Exit fullscreen mode


If the shortenedUrl doesn't exist we add it to the database with the structure defined earlier above and send back the shortenedUrl.

let status = await addUrl(url, shortenedUrl);
if (status?.acknowledged) return res.json({ shortenedUrl });
else return res.json({ error: true }); // Not to make the server crash
Enter fullscreen mode Exit fullscreen mode


'/shrink' route in one snippet

app.post("/shrink", async (req, res) => {
  let { url } = req.body;
  let shortenedUrl = createUrl(url);
  let result = await findUrl(shortenedUrl);
  if (result.length >= 1) return res.json({ shortenedUrl });
  let status = await addUrl(url, shortenedUrl);
  if (status?.acknowledged) return res.json({ shortenedUrl });
  else return res.json({ error: true });
});
Enter fullscreen mode Exit fullscreen mode
  • Strecth URL

To stretch URL we are going to define a GET route

First we define the route in api.js

app.get("/s/:shortUrl", async (req, res) => {
  ...
});
Enter fullscreen mode Exit fullscreen mode


The :shortUrl in the route section capsules all the section after '/s/' into a variable.

First we check if the url is in the database or not. If it's in the database we redirect the user to the URL or we send a 404 message

let { shortUrl } = req.params;
let result = await findUrl(shortUrl);
if (result.length > 0) return res.redirect(result[0]?.url);
else res.json({ 404: "no URL found" });
Enter fullscreen mode Exit fullscreen mode


'/s/:shortUrl' route in one snippet

app.get("/s/:shortUrl", async (req, res) => {
  let { shortUrl } = req.params;
  let result = await findUrl(shortUrl);
  if (result.length > 0) return res.redirect(result[0]?.url);
  else res.json({ 404: "no URL found" });
});
Enter fullscreen mode Exit fullscreen mode

And voila you have a working link shortner 🎉🎉🎊
Here's a working link shortner shrinkinglinks

Top comments (2)

Collapse
 
thomasbnt profile image
Thomas Bnt

Hello good post ! Don't hesitate to put colors on your codeblock like this example for have to have a better understanding of your code 😎

console.log('Hello world!');
Enter fullscreen mode Exit fullscreen mode

Example of how to add colors and syntax in codeblocks

Collapse
 
prajyu profile image
prajyu

Yeah thanks i will