Skip to content
Dimitris Pramateftakis edited this page Nov 27, 2021 · 5 revisions

Here you can find some brief documentation about the project like Requirements, design, architecture and production setup.

Requirements

Functional Non-functional
A user can enter an arbitrary URL "X" on the website and get a shortened URL in return. Component-based frontend framework (like React, Vue, Next.js).
On visiting the shortened URL, the user gets redirected to "X". Node.js-based Backend (like Express, Nest.js, etc. Serverless)
The shortening has to be idempotent, i.e. a given URL always has to yield the same short URL as a result. Versioning using git.
On the website, the user can also see stats for all shortUrls that have been generated (by anyone) on the site:
- For each shortUrl, how often did someone attempt to shorten that specific URL?
- For each shortUrl, how often was it visited?
Code is written in a testable way so you can unit test the core logic.
Deployment pipeline notes

Design

After analyzing the requirements I started thinking about a really simple, minimal and as user friendly as possible design for the frontend. My design process consisted of 4 stages: Inspiration, colors, draft and final product. Starting from the first stage I checked out and borrowed some inspiration from tinyurl's layout which I found it pretty functional and a good starting point. Afterwards, I visited https://colorhunt.co/ and carefully picked out this color palette after trying out on a draft figma project some shapes and combinations. Moving to the next stage, I created a new Figma draft and started creating the Desktop version first. Although the actual web application is created using a mobile-first approach, I find it a bit easier to first design the desktop layout and then the mobile. After finishing the mobile design too, I finally settled on this design:

Figma Design

Architecture

I decided to split the frontend and the backend into separate applications because this allows for more flexibility in terms of deploying, scaling etc. Although the frontend and the backend are separate projects I settled on a github monorepo for code hosting. Monorepos for such small projects are very easy to manage and I find many benefits in utilizing them.

For the tech stack I went with React and Express as I am more familiar with them and MongoDB because it suits very well for similar usecases such as this project.

Web app arch

API Endpoints

quickurl.live/api/test      // GET: Returns a simple message to test if the api is working
quickurl.live/api/shorten   // POST: Accepts a normal URL and returns a new quickurl object
quickurl.live/api/fetchAll  // GET: Returns a list with all the available quickurls
quickurl.live/r/:shortId    // GET: Redirects a URL

Quickurl(shorturl) mongodb Schema

- url
- shortId
- visits
- attemps

As a bonus I used docker and docker-compose to make all the development portable and plug-and-play which made things a lot easier.

docker-setup

Production

As far as production goes I made some small sacrifices in order to complete this project in a reasonable amount of time. I decided to stick with the docker containers and docker-compose although docker-compose is not suggested for production environments. For the server I used a digital ocean droplet 1 GB Memory / 1 AMD vCPU / 25 GB Disk / FRA1 with a Docker 19.03.12 on Ubuntu 20.04 image from the marketplace.

production

The workflow is not the best but that's another sacrifice I had to make.

To push a new version on the droplet I copy all the project files (without the node_modules) via scp command and then I build and deploy the images from there. A better way to do this is to implement a CI/CD pipeline on a platform like github actions to build the docker images and then push them on a docker registry like docker hub. Then you would pull the images from there on to the server with the help of a bash script and using something like docker swarm instead of docker compose for production and scaling.

On a sidenote, using mongodb as an image the way I did it is not very safe and I would definitely use something like atlas for database hosting as it provides better authentication and it is overall a more secure and stable solution.

Clone this wiki locally