DEV Community

Cover image for Building a url shortener for fun and no profit!

Posted on

Building a url shortener for fun and no profit!

This was a fun full stack project weeknight project and I learned a lot while doing it and would love to share the process with you all!

When starting any project it we should start by working through the SDLC to maximize our productivity and minimize wasted time.

Stage One - Planning

Q: What are we trying to build?

A: A URL Shortener.

Q: Why?

A: It's a fun project!

Stage Two - Analysis

Q: Is this something people would use?

A: Totally! There are many out there, but this one is mine.

Q: Potential for abuse?

A: Yes, must consider mitigations.

Q: Am I worried about monetization?

A: Not so much.

Stage Three - Design

Let's think about what we want our user experience (UX) to be once they land on our page. I want this to be simple and easy

Front End

Going for a very simple google-esque design and using a design mockup tool I settled on something like this. mockup image

Back End

The backend is the workhorse of this application, it has TWO main jobs.

  1. Shorten Links
  2. Unshorten Links
def shorten(val):
    # Take a "long" value and return a "short" value

def unshorten(val):
    # Take a "short" value and return its corresponding "long" value

All of our data will be stored in a database and for our purposes I chose to use SQLite, although for this implementation any database where you can have a unique primary key for every entry will work fine. If you want to use another method, you're on your own. For our short url purposes we only want to have valid, non special characters; upper and lowercase alphabet a-z,A-Z and numbers 0-9. This gives us a key space of 62 characters or base62; our database uses just numbers, or base10.

Cool! Heavy lifting done!

Long to short => base10 -> base62

Short to long => base62 -> base10

from baseconvert import base

def shorten(val):
    # Take a "long" value and return a "short" value
    return base(val, 10, 62, string=True)

def unshorten(val):
    # Take a "short" value and return its corresponding "long" value
    return base(val, 62, 10, string=True)

Lets add some API endpoints using Flask

from flask import Flask
import sqlite3

app = Flask(__name__)
db = sqlite3.connect('file.db')

@app.route('/add', methods=['POST']):
def add_url():
    # Add url to database & get ID
    row_id = db.add(url).lastrowid
    # shorten
    short_id = shorten(row_id)
    # return to user
    return short_id

@app.route('/<string:shortURL>', methods=['GET']):
def get_url(shortURL):
    # lengthen row id value (shortURL)
    row_id = unshorten(shortURL)
    # get url from database
    row = db.get(row_id)
    # return to user
    return row['url']

We've got our big pieces designed out and some psudocode written; it's time to move to the next stage!

Stage Four - Implementation

There is no public repo for my code but check out the running implementation here -

Front end is hosted for free on netlify, backend & database is hosted on Digital Ocean on small droplet.

Security was kept in mind during the implementation of the project. Recaptcha is used to minimize automated shortlinking and of course this is validated on the backend as well as front.

A feature I would like to add at a later date is VirusTotal link rating to mitigate any malicious actors using this service to deliver payloads or bypass network filtering devices.

Stage Five - Testing & Integration

I spent an afternoon testing and securing this application. This was a really fun project and I'm receptive to any and all bug or vulnerability reports, there's always something to learn and improve on.

Stage Six - Maintenance

So far so good, I've knocked down all the items and bugs on my list. Did I miss any?


Enjoyed the post? Let me know! πŸ’›πŸ¦„πŸ”–

Top comments (3)

ben profile image
Ben Halpern

Worked like a charm

0xbanana profile image

phew! Im glad!

thassio__ profile image
Thassio Victor