Create a URL Shortener Project using MongoDB + Node - but hands-on!
Tags: javascript, webdev, beginners, node
Published: 2020-09-18 23:09:32

---
title: Create a URL Shortener Project using MongoDB + Node - but hands-on!
published: true
description: In this blog post, we'll learn about MongoDB, Mongoose, Node, and another tech by building a simple URL shortener application. The difference? You will actually build a project instead of just watching a video or reading a blog.

tags: javascript, webdev, beginners, node
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/zosw1rnqkilthqi41rtf.jpg
---

Let us learn about MongoDB, Mongoose, Node, and other tech by building a simple URL shortener project.

Have you ever wondered how you could create a quick URL shortener for yourself? Like how twitter shortens your links when you share them? Or how bit.ly works?

Sure enough, these are complicated companies, but the concept for URL shorteners is simple. Let's learn about MongoDB and other backend tools by actually building this project in 7 steps.

# Introduction to Project

We will be using this [free URL shortener classroom](https://codedamn.com/practice/url-shortener-node) from codedamn to really, like really create and evaluate our hands-on project and see the feedback.
 
We will be using the following technologies:

- Mongoose as the ORM
- MongoDB as the backend database
- Node.js as the backend
- A simple embedded JS file as the frontend

# Lab 1: Setting up the Express server

![Lab 1](https://dev-to-uploads.s3.amazonaws.com/i/545m9ait9as8oih7alib.png)

The link of this [lab is here](https://codedamn.com/practice/url-shortener-node/36280bc2-36b5-4f4e-8976-ed4687dc7cbd)

It's a fairly straightforward lab. We have to just create a route `/short` which should respond appropriately. This code would let us pass:

```js
// Initialize express server on PORT 1337
const express = require('express')
const app = express()

app.get('/', (req, res) => {
	res.send('Hello World! - from codedamn')
})

app.get('/short', (req, res) => {
	res.send('Hello from short')
})

app.listen(process.env.PUBLIC_PORT, () => {
	console.log('Server started')
})
```

# Lab 2: Setting up our view engine

![Lab 2](https://dev-to-uploads.s3.amazonaws.com/i/tniqqbsh3euadrko2vla.png)

The link of this [lab is here](https://codedamn.com/practice/url-shortener-node/0eb7b0b0-473e-4a83-9589-8ea13467972f)

We're using a single `.ejs` file, so let's explore that a little. Again, a very simple lab because we just have to change the name of the variable. This should get us done:

```js
const express = require('express')
const app = express()

app.set('view engine', 'ejs')

app.get('/', (req, res) => {
	res.render('index', { myVariable: 'My name is John!' })
})

app.listen(process.env.PUBLIC_PORT, () => {
	console.log('Server started')
})
```

# Lab 3: Setting up MongoDB

![Lab 3](https://dev-to-uploads.s3.amazonaws.com/i/17mk2gxzaxx3szye6o6q.png)
 
The link of this [lab is here](https://codedamn.com/practice/url-shortener-node/523eaae7-27ff-47fe-bfdc-67a65dfd5711)

In this lab, we'll connect to MongoDB correctly and insert a record, just _for the record_

This is the solution which should get us to the next lab:

```js
app.post('/short', (req, res) => {
	const db = mongoose.connection.db
	// insert the record in 'test' collection
	db.collection('test').insertOne({ testCompleted: 1 })

	res.json({ ok: 1 })
})

// Setup your mongodb connection here
mongoose.connect('mongodb://localhost/codedamn', {
	useNewUrlParser: true,
	useUnifiedTopology: true
})
mongoose.connection.on('open', () => {
	// Wait for mongodb connection before server starts
	app.listen(process.env.PUBLIC_PORT, () => {
		console.log('Server started')
	})
})
```

# Lab 4: Setting up a Mongoose schema

![Lab 4](https://dev-to-uploads.s3.amazonaws.com/i/8n5v6u7lgx13o7e814jk.png)
 
The link of this [lab is here](https://codedamn.com/practice/url-shortener-node/a64e6946-a6ea-4ba7-8357-fe000c61658c)

Finally, we define a schema in the `models/url.js` file for proper handling with Mongoose, and here's the code for that:

```js
const mongoose = require('mongoose')
const shortId = require('shortid')

const shortUrlSchema = new mongoose.Schema({
  full: {
    type: String,
    required: true
  },
  short: {
    type: String,
    required: true,
    default: shortId.generate
  },
  clicks: {
    type: Number,
    required: true,
    default: 0
  }
})

module.exports = mongoose.model('ShortUrl', shortUrlSchema)
```

Also, as part of the challenge, we update the `/short` route now.

```js
app.post('/short', async (req, res) => {
	// insert the record using the model
	const record = new ShortURL({
		full: 'test'
	})
	await record.save()
	res.json({ ok: 1 })
})
```


# Lab 5: Linking the frontend, backend, + MongoDB

![Lab 5](https://dev-to-uploads.s3.amazonaws.com/i/gb866nzm8buec6s9nq8e.png)

This is also a simple lab. We just have to update the route to extract the URL passed and store it in the database using our schema.

```js
app.use(express.urlencoded({ extended: false }))

app.post('/short', async (req, res) => {
	// Grab the fullUrl parameter from the req.body
	const fullUrl = req.body.fullUrl
	console.log('URL requested: ', fullUrl)

	// insert and wait for the record to be inserted using the model
	const record = new ShortURL({
		full: fullUrl
	})

	await record.save()

	res.redirect('/')
})
```

# Lab 6: Displaying short URLs on the frontend

![Lab 6](https://dev-to-uploads.s3.amazonaws.com/i/lhi7puwkir2gwbi6e6qa.png)

Now, we display the URL set on our website using the `.ejs` variables passed.

```js
app.get('/', async (req, res) => {
	const allData = await ShortURL.find()
	res.render('index', { shortUrls: allData })
})
```

# Lab 7: Making the redirection work

![Lab 7](https://dev-to-uploads.s3.amazonaws.com/i/jcoavfyy0dy3gracnphq.png) 

Finally, we link up the redirection scheme using dynamic express routes and correct status codes.

```js
app.get('/:shortid', async (req, res) => {
	// grab the :shortid param
	const shortid = req.params.shortid

	// perform the mongoose call to find the long URL
	const rec = await ShortURL.findOne({ short: shortid })

	// if null, set status to 404 (res.sendStatus(404))
	if (!rec) return res.sendStatus(404)

	// if not null, increment the click count in database
	rec.clicks++
	await rec.save()

	// redirect the user to original link
	res.redirect(rec.full)
})
```

# Conclusion

And we can call it a day! You just built a fully working URL shortener by yourself using Express + Node + MongoDB. Give yourself a pat on back!

The final source code is available on [GitHub](https://github.com/codedamn-classrooms/node-mongodb-url-shortner/tree/lab7-sol).

If you have any feedback on this article or codedamn classrooms, feel free to reach out to me on Twitter. Let's discuss :)