URL Shorteners:- A Practical Approach, Mini Project
๐ฅ A Real world example of Tiny URL with beginner friendly implementation
๐ Introduction
๐ฏ In today's world, we do share many things over the internet. And one of the methods of sharing is to share the URL of the content. We use Google drive to store, Youtube for Videos, Spotify for Music, etc. Whenever we want to share something from any platform the most common way is to share the URL.
๐ฉ But sometimes, the URL gets too long or not making sense like Google Drive URLs (drive.google.com/drive/u/1/folders/1oue1LJP..)
๐ So, here is where we can use URL shorter services like Bit.ly, TinyURL, etc.
๐ 301, 302 Status Code
๐ Sometimes you can see that in the Network tab of our browser Inspect tools we do get 301 or 302 Moved Permanently as the Status code. This means that the URL is going to redirect us to the main URL.
๐ Here, you can see when I opened Google Maps through the TinyURL link It gave me the code 301 which means it is going to redirect us to the main URL.
Note:- We'll see a basic implementation of the service, to let you guys know what are the basic requirements that a URL Shorteners should have.
Register a New Long URL
Register a New Long URL with Custom Short URL
Get a Long URL by providing a Short URL
Get the count of how many times a long URL visited
Deleting a long URL from the store
๐ To get a better idea, Follow this:-
๐ค Note:- Here, we took a shortURL of syntax:- shortURL.com/xxxxxxxxx
Where, xxxxxxxxx is an AlphaNumeric String of length 9.
Below, you can find the implementation with a main file to test the code:-
- URLShortnerInterface
package com.project.shorturl;
public interface URLShortnerInterface {
String registerNewUrl(String longUrl);
String registerNewUrl(String longUrl, String shortUrl);
String getUrl(String shortUrl);
Integer getHitCount(String longUrl);
String delete(String longUrl);
}
Here, We have used an interface to follow some Design patterns.
- URLShortnerImplementation:-
package com.project.shorturl;
import java.util.HashMap;
public class URLShortnerImplementation implements URLShortnerInterface {
HashMap<String, String> map1; // longUrl->ShortUrl
HashMap<String, String> map2; // ShortUrl->longUrl
HashMap<String, Integer> map3; // longUrl->Integer
URLShortnerImplementation(){
map1 = new HashMap<>();
map2 = new HashMap<>();
map3 = new HashMap<>();
}
public String generateString(){
String AlphaNumericString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"+ "0123456789";
String result = "";
for(int i = 0; i<9; i++){
result += AlphaNumericString.charAt((int)(result.length()*Math.random()));
// System.out.println("Generated String is : "+ result);
}
// System.out.println("-------");
return result;
}
@Override
public String registerNewUrl(String longUrl){
if(map1.containsKey(longUrl)){
return map1.get(longUrl);
}
String shortUrl = generateString();
shortUrl = "http://short.url/"+shortUrl;
map1.put(longUrl, shortUrl);
map2.put(shortUrl, longUrl);
return shortUrl;
}
public void printMap(){
System.out.println("Map1");
for(String key: map1.keySet()){
System.out.println();
System.out.print(key+" ");
System.out.print(map1.get(key));
}
System.out.println("Map2");
for(String key: map2.keySet()){
System.out.println();
System.out.print(key+" ");
System.out.print(map2.get(key));
}
System.out.println();
System.out.println("-----");
}
@Override
public String getUrl(String shortUrl){
if(map2.containsKey(shortUrl)){
if(map3.containsKey(map2.get(shortUrl))){
map3.put(map2.get(shortUrl), map3.get(map2.get(shortUrl))+1);
}else{
map3.put(map2.get(shortUrl), 1);
}
return map2.get(shortUrl);
}
return null;
}
@Override
public String registerNewUrl(String longUrl, String shortUrl){
if(map2.containsKey(shortUrl)){
return null;
}
map1.put(longUrl, shortUrl);
map2.put(shortUrl, longUrl);
return shortUrl;
}
@Override
public Integer getHitCount(String longUrl){
if(map3.containsKey(longUrl)){
return map3.get(longUrl);
}
return 0;
}
@Override
public String delete(String longUrl){
if(map1.containsKey(longUrl)){
map2.remove(map1.get(longUrl));
map1.remove(longUrl);
}
return null;
}
}
- The main method to test the functionalities:-
package com.project.shorturl;
public class URLShortnerMain {
public static void main(String[] args) {
URLShortnerImplementation UrlShort = new URLShortnerImplementation();
String url = UrlShort.registerNewUrl("http://abc.com");
String url1 = UrlShort.registerNewUrl("http://abc1.com");
String url2 = UrlShort.registerNewUrl("http://abc2.com");
String url3 = UrlShort.registerNewUrl("http://abc3.com");
String url4 = UrlShort.registerNewUrl("http://abc2.com");
System.out.println(url);
System.out.println(url1);
System.out.println(url2);
System.out.println(url3);
System.out.println(url4);
// Update new URL mapping to a custom short URL
String url5 = UrlShort.registerNewUrl("http://abc5.com", "http://short.url/test1");
String url6 = UrlShort.registerNewUrl("http://abc6.com", "http://short.url/test2");
// Try to update new URL to map to existing short URL, should return null
String urlNull = UrlShort.registerNewUrl("http://abc7.com", url3);
assert(urlNull == null);
System.out.println(url5);
System.out.println(url6);
System.out.println(urlNull);
// Test out longURL lookup based on the shortURL input
assert(UrlShort.getUrl(url).equals("http://abc.com"));
assert(UrlShort.getUrl(url2).equals(xUrl.getUrl(url4)));
assert(UrlShort.getUrl(url5).equals("http://abc5.com"));
// Test out getHitCount() for a given long URL.
// Here the same long URL has been looked up 2 times as part of url2 & url4
assert(UrlShort.getHitCount("http://abc2.com").equals(2));
// Try to fetch hit count for a non existent long URL, should return 0
assert(UrlShort.getHitCount("http://abcn.com").equals(0));
// From the short URL url1, remove the common section (http://short.url/) and remove any non alphanumeric character
String choppedUrl = UrlShort.replace("http://short.url/", "").replaceAll("[^A-Za-z0-9]", "");
System.out.println(choppedUrl);
// The result should have only alphanumeric characters and be 9 characters long
assert (choppedUrl.length() == 9);
// Delete mapping for the long URL and confirm that the short URL lookup for that long URL returns null
UrlShort.delete("http://abc6.com");
assert(UrlShort.getUrl(url6) == null);
}
}
๐ซต There are some assertions embedded to test the code. This was the basic implementation or introduction.
๐ค We can add Database support and notifications like if
Custom Short URL already taken
URL is deleted or not, etc
๐ป Our Next Blogs are going to be on DevOps, Scaling infrastructure, and Low-Level Design.
๐ฅ For more, Follow RealCS