10 Minutes Implementation of Short Link Service (Node + Express + MongoDB)

Posted by mansuang on Wed, 21 Aug 2019 11:16:42 +0200

Short links are more or less used by us. The so-called short links are to generate a shorter link according to the long original link url. Visiting short links can jump to the corresponding original link. This is good in: 1. url is more beautiful; 2. It is easy to save and disseminate; 3. Some websites have word limit in content publishing, short links. It can save the number of words.

The principle of short link implementation is very simple, which can be summarized as follows:

  1. Generate unique short links without duplication for each original link
  2. Save original links and corresponding short links in pairs to the database
  3. When accessing short links, the web server redirects the target to the corresponding original link

According to the above ideas, we can also implement a short link generation service in minutes. This example uses node + express + mongodb.

1. Initialization project

(1) Installation of the following dependencies:

package.json:

"dependencies": {
  "config": "^3.2.2", // Read project configuration
  "express": "^4.17.1", // web server
  "mongoose": "^5.6.9", // Manipulating mongodb
  "shortid": "^2.2.14", // Generate a unique Id that does not repeat
  "valid-url": "^1.0.9" // Determine whether the url format is correct
}

(2) Increase project configuration:

It is mainly used to store connection strings and base URLs for short links in MongoDB.

config/default.json:

{
  "mongoURI": "mongodb://localhost:27017/url-shorten-service",
  "baseUrl": "http://localhost:5000"
}

(3) Adding MongoDB Connection Method

config/db.js:

const mongoose = require('mongoose');
const config = require('config');
const db = config.get('mongoURI');

const connectDB = async () => {
  try {
    await mongoose.connect(db, {
      useNewUrlParser: true
    });
    console.log(`MongoDB Connected to: ${db}`);
  } catch (error) {
    console.error(error.message);
    process.exit(1);
  }
}

module.exports = connectDB;

(4) Start express:

index.js:

const express = require('express');
const connectDB = require('./config/db');

const app = express();

// Connect MongoDB
connectDB();

app.use(express.json({
  extended: false
}));

// Routing, set up later
app.use('/', require('./routes/index'));
app.use('/api/url', require('./routes/url'));

const port = 5000;

app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

2. Define the database model

We need to save the original link and the corresponding short link to the database. For simplicity, we only need to save a short link code. The corresponding short link can be made by splicing base url and code.

models/url.js:

const mongoose = require('mongoose');

const urlSchema = new mongoose.Schema({
  urlCode: String,
  longUrl: String
});

module.exports = mongoose.model('Url', urlSchema);

3. Generating Short Link Coding

This is a key step for us to achieve, the idea is: users pass in a long link, we first use valid-url To judge whether the incoming url is legitimate or not, an error is returned. If it is legitimate, we search the database for the record of the long link. If it is, we return the record directly. If it is not, a new record is generated and the corresponding short link is generated. With the help of shortId We can easily generate a unique code without duplication.

routes/url.js:

const epxress = require("express");
const router = epxress.Router();
const validUrl = require('valid-url');
const shortId = require('shortid');
const config = require('config');
const Url = require('../models/url');

router.post('/shorten', async (req, res, next) => {
  const { longUrl } = req.body;
  if (validUrl.isUri(longUrl)) {
    try {
      let url = await Url.findOne({ longUrl });
      if (url) {
        res.json({
          shortUrl: `${config.get('baseUrl')}/${url.urlCode}`
        });
      } else {
        const urlCode = shortId.generate();
        url = new Url({
          longUrl,
          urlCode
        });
        await url.save();
        res.json({
          shortUrl: `${config.get('baseUrl')}/${urlCode}`
        });
      }
    } catch (error) {
      res.status(500).json('Server error');
    }
  } else {
    res.status(401).json('Invalid long url');
  }
});

module.exports = router;

4. Access short links and jump to original links

The last step is very simple. When the user visits the short link we generate, we query the corresponding record according to the short link code in the url. If there are corresponding records, we use the res.redirect method of express to redirect the access to the original link, and if there are no corresponding records, we return the error.

routes/index.js

const epxress = require("express");
const router = epxress.Router();
const Url = require('../models/url');

router.get('/:code', async (req, res, next) => {
  try {
    const urlCode = req.params.code;
    const url = await Url.findOne({ urlCode });
    if (url) {
      // Redirect to the original link
      res.redirect(url.longUrl);
    } else {
      res.status(404).json("No url found");
    }
  } catch (error) {
    res.status(500).json("Server error");
  }
});

module.exports = router;

Test it:

Access short links:

In this way, a simple short link generation service is completed, and the principle and implementation behind the magic technology is very simple. I hope this article can inspire you.

This article Demo address: https://github.com/MudOnTire/...

Topics: node.js JSON Mongoose MongoDB Database