Skip to content

Latest commit

 

History

History
238 lines (182 loc) · 7.44 KB

README.md

File metadata and controls

238 lines (182 loc) · 7.44 KB

Shortify

url shortner Application

Overview
Introducing "Shortify": a simple URL shortening service built with Nest.js and TypeScript. Shortify offers advanced analytics capabilities, empowering users to track click-through rates, geographic distribution, and referral sources. With its robust backend system, Shortify ensures reliability, efficiency, and scalability, even under heavy traffic loads. Simplify your link management and gain valuable insights with Shortify.

Technologies Used
  • Nest.js
  • TypeScript
  • PostgreSQL
  • Redis
  • Jest

How to setup and run

Local Setup

Make sure you have the following installed on your system:
  • Node
  • Postgres
  • Redis
  1. Fork this repo
  2. Clone this repo
  3. git clone git@github.com:Flanker-shyam/Shortify.git
  4. install dependencies
  5. npm install
  6. Setup Environment variables:
    • Create a .env file in the root dir of this project
    • Copy content of example.env into this file
    • Change dummy values accordingly
  7. Setup Database
    • Start local Postgres server
      For MacOS
      brew services start postgresql

      For Linux

      sudo systemctl start postgresql
    • Create Database: url_shortner/or choose any db name
    • Run DB migration to push DB schemas to the DB
      npm run migration:run
  8. Redis setup
    • Start local Redis server
      For MacOS
      brew services start redis

      For Linux

      sudo systemctl start redis
  9. Run and test
  10. Run this project
    • To run
      npm run start
    • To run in watch mode
       npm run start:dev
    • To run test
      npm run test

Run using podman

  1. Install podman in your machine (follow google)
  2. Change following variables in .env file
    DATABASE_HOST=localhost
    REDIS_HOST=localhost
  3. start script
    ./create-pod.sh 

    This will pull redis and postgres images and create three containers and run the whole application inside a pod shortify_pod.

  4. destroy script
    ./destroy-pod.sh shortify_pod

    This will destroy the pod along with all the containers running inside it.

  5. Setup done!!!!

Docker container Setup

  1. Change following variables in .env file
    DATABASE_HOST=postgres
    REDIS_HOST=redis
  2. Create docker container
    docker compose up -d

    This will pull redis and postgres images and containarize the whole application with it's dependencies

  3. Setup done!!!!

Approach of Implementation

ER diagram image

Approach Documentation

URL Shortener Solution

Overview

The URL shortener solution provides users with the ability to shorten URLs and obtain detailed analytics for their shortened URLs. It includes authentication and authorization mechanisms for accessing analytics, employs security measures to prevent vulnerabilities, and focuses on performance and scalability.

Functionalities

  1. URL Shortening: Users can pass a long URL and receive a corresponding short URL. If the long URL already exists in the database, the system returns the existing short URL; otherwise, it generates a new short URL using SHA-256 hashing and take the first 8 characters of the hash; although teh chances of collision are very rare but still here to maintain the uniqueness of shortUrl I am using while loop and every time I am checking if the shortUrl exist in the db or not.

  2. Fetch URL Data: The system checks Redis cache for the short URL mapping. If found, it redirects the user and saves analytics. If not found, it checks the database. If the URL exists in the database, it saves the mapping in Redis, redirects the user, and saves analytics. If the URL is not found in either Redis or the database, it returns a "URL not found" error.

    Save Analytics: This function extract info from the request header like: User-agant, referer and store it in analytics table along with other data like timeStamp.

  3. Get Analytics: Users can retrieve analytics for their URLs by providing their username. The system fetches all URLs created by the user and retrieves analytics data for each URL. The analytics include user-agent, referral source (or "Direct" if not available), timestamp, and number of clicks(number of clicks===size of analytics array).

  4. Authentication and Authorization: Users need to register and log in to access the analytics feature. Upon successful login, users receive an authentication token, which they can use to authorize access to their analytics data. This ensures that users only have access to their own URLs and associated analytics.

Security Measures

  • Input Validation: Validate input data before performing database actions to prevent SQL injection attacks.
  • CORS: Implement Cross-Origin Resource Sharing to restrict access from unauthorized domains.
  • Helmet: Use Helmet middleware to set various HTTP headers for enhanced security.
  • Rate Limiting: Implement rate limiting to prevent abuse of the service and mitigate Denial-of-Service attacks.
  • Authentication: Implement secure user authentication mechanisms to ensure only authenticated users can access their analytics data.
  • Authorization: Authorize access to analytics data using authentication tokens to ensure users can only access their own data.

Performance Enhancements

  • Redis Cache: Utilize Redis caching to improve performance by storing frequently accessed URL mappings.
  • Docker Containerization: Package the application and its dependencies into Docker containers for portability and efficiency.

Testing

  • Unit Tests: Develop unit tests to verify the functionality of individual components and ensure code quality.
  • Integration Tests: Plan to add integration tests to validate the interaction between different modules and cover various use cases comprehensively.

Future Enhancements plan to do

  • Load Balancing and DB Sharding:
  • LOAD BALANCING: For load balancing as my application is already running in docker container, I will be using NGINX as a reverse proxy server along with Round-Robin algorithm

docker run --name redis -d -p 6379:6379 redis

docker run --name postgres -d -e POSTGRES_USER=flanker -e POSTGRES_PASSWORD=flanker -e POSTGRES_DB=url_shortner -p 5432:5432 postgres

docker run --name nest-app -p 3000:3000 --link redis --link postgres -e POSTGRES_HOST=postgres -e POSTGRES_PORT=5432 -e POSTGRES_DB=url_shortner -e POSTGRES_USER=flanker -e POSTGRES_PASSWORD=flanker -e REDIS_HOST=redis -e REDIS_PORT=6379 flanker1916/shorty:1

podman:

podman pod create --name shortify_pod -p 3000:3000 -p 5432:5432 -p 6379:6379

podman run --pod myfirst -e POSTGRES_USER=flanker -e POSTGRES_PASSWORD=flanker -e POSTGRES_DB=url_shortner --name postgres postgres

podman run --pod myfirst --name redis redis

podman run --pod myfirst --name myAPP myapp