DEV Community

Cover image for URL shortening using CLI
Sourab Pramanik
Sourab Pramanik

Posted on • Edited on

URL shortening using CLI

This project is built using Vercel, Neon, and Rust. It is a link-managing application that has a CLI to create, read, and delete short URLs. I have used Vercel to deploy a serverless function that is used for redirections. This whole setup is designed to be self-hosted which enables more control, complete customizations, and low-to-no cost on usage.

What is a URL shortener and why do we need it?

URL shortener is a service that is used to create short URLs that work as an alias for long URLs, this is important when you have a long URL (e.g. https://chart.apis.google.com/chart?chs=500x500&chma=0,0,100,100&cht=p&chco=FF0000%2CFFFF00%7CFF8000%2C00FF00%7C00FF00%2C0000FF&...) and sharing this is not that neat when it comes to branding, email marketing, and what if you snap out some characters at the end of the URL while copying? invalid URL now.

It becomes really hard this way, that is where we can use a URL-shortening service that can generate an alias for the long URLs having comparatively shorter lengths. The other benefits of having short URLs or aliases are you can customize how you want your URL to appear(e.g. https://foo.baz/2fGH553), generate analytics like the number of users clicked, country of origin, protect with passwords, and many more.

Many big companies like Twitter or X use this service for sharing any content outside their application. This helps them to maintain brand aesthetics, market themselves better, and keep things clean and concise.

How does it work?

Flow diagram

The user enters the short URL, and every short URL must have a path, the path acts as a unique identifier, and using this we query the database to find the record.

If there exists a record then we will send the browser the long URL to the browser to redirect the user to the destination page, the redirection can be temporary or permanent there are trade-offs on using one over the other. Once the browser receives the it will open the redirected page.

If the record doesn't exist or the path is not what was expected then the user will get a 404 status page.

As simple as that!!!

Pre-requisites

Setup

Open your terminal window, clone the repository at any desired location in your machine, and go inside the project folder using these commands:

git clone https://github.com/sourabpramanik/shorten-url.git
cd shorten-url
Enter fullscreen mode Exit fullscreen mode

Create a Postgres database

I appreciate Neon and the team behind it, they ingeniously crafted everything around the standard Postgres database so neatly and expanded the scope to use Postgres in different domains without any overhead. Not to mention they also have a humble open-source community.

  1. Go to their website, log in, or create an account.

  2. Create a project and a database, name them whatever you want:

Create project

  1. Go to your project dashboard, select your database, and copy the connection string, you will need this connection string later: Get connection string

Deploy serverless function Vercel

Deploying projects on Vercel is completely free in hobby accounts, and you can add custom domains to your projects if you have however by default Vercel will generate a production URL for your project.

  1. Build the serverless function:

    vercel build --prod --cwd ./shorten-url-functions
    

    --prod flag will build the function with all the configurations needed by Vercel to deploy and run this function in the production environment.

    After the build is completed it generates .vercel directory in the root, which has all the directories and configuration files containing lots of information like the runtime, project name, entry point, filesystem mappings, target environment, packages used, commands to be executed and so on.

    If you are curious to know more about it then go ahead and tweak things here and there (at your own risk) as long as everything works as expected.

  2. Deploy the build output:

    vercel deploy --prebuilt --prod --cwd ./shorten-url-functions
    

    --prebuilt flag is for Vercel to locate the output directory inside the .vercel and deploy it to production

    Only if this is the first time you are deploying this project then you have to answer some of the prompts. This is needed by Vercel to make sure your project is deployed properly with any alternate approach you may have.

  3. Add environment variables:

    vercel env add DATABASE_URL --cwd ./shorten-url-functions
    

    a prompt will appear asking for the value, paste the database connection string copied from the Neon project dashboard.

    You will need to deploy the function again using the command from step 2 so that the deployed function can use the newly added environment variable, most of the time it is not needed but it's better to make sure

  4. That's it with the serverless function deployment, now we need to get the domain.

    If you have a custom domain and want to use it as the domain for creating short URLs then follow this doc link

    Or else if you want to use the domain generated by Vercel for your project then go to the project dashboard and copy the domain name.

Install and configure CLI

  1. To install the CLI run this command:

    cargo install --path ./shorten-url-cli
    
  2. Configuring the CLI:
    run the below command and use these when prompted:

    shortenurl config
    

    Get these:

    • Postgres connection string from Neon projects dashboard
    • Domain name of the deployed serverless function

    And use it when prompted

    ? Provide postgres connection string:
    ? Provide primary domain configured in Vercel(e.g. foo.com):
    

    After the migration completes, your config will be saved in a shortenurl.toml file inside the config directory. Look up at these locations depending on your Operation System to locate the config file:

Linux

vim /home/<username>/.config/shortenurl/shortenurl.toml       
Enter fullscreen mode Exit fullscreen mode

Windows

vim C:\Users\<username>\AppData\Roaming\shortenurl\shortenurl.toml
Enter fullscreen mode Exit fullscreen mode

Mac

vim /Users/<username>/Library/Application Support/shortenurl/shortenurl.toml
Enter fullscreen mode Exit fullscreen mode
  1. That's it, we have finally completed the setup.

Usage

Create a short URL

shortenurl alias create <URL>
Enter fullscreen mode Exit fullscreen mode

This will generate an alias for the short URL and creates a record in the database. If the provided URL already exists then it will throw an error.

Get long and short URLs by alias

shortenurl alias get <alias>
Enter fullscreen mode Exit fullscreen mode

If you have an alias (e.g. U9uaR8C) but are not sure which long URL it belongs to then use this command.

List all records

shortenurl alias get-all
Enter fullscreen mode Exit fullscreen mode

This command will list out all the short URLs and the respective long URLs

Remove a record by the alias

shortenurl alias remove-alias <alias>
Enter fullscreen mode Exit fullscreen mode

To remove a short URL and its respective long URL, you can use this command by providing the alias(e.g. U9kHB4Z)

Remove all records

shortenurl alias flush
Enter fullscreen mode Exit fullscreen mode

Like it says flushes out everything.

Be careful when you remove a record because you may have used these short URLs at some other places, removing them and using these short URLs again will give 404.

Conclusion

This was a fun project for me and has lots of scope for new features like analytics, caching, real-time logging, URL grouping by domain name, and so on. But for now, this is it, if you think this project can be used as an alternative to other similar products out there because of the control, minimal to no cost, and hell lot of customizations it provides then let me know here, I would be happy to craft this for production use.

Signing out!!!

Top comments (8)

Collapse
 
sehgalspandan profile image
Spandan Sehgal

I would be a definite user for this product! (Gotta work a lot with links these days 🤣)

Good work, you can reach me out for help!

Btw, It would be great if you take a look at this post: dev.to/spandan/how-can-i-improve-m...

Actually I am collecting feedback for my posts and looking for the areas that I can improve

Thank you!

Collapse
 
skipperhoa profile image
Hòa Nguyễn Coder

thanks you!

Collapse
 
helio609 profile image
Helio

That's cool!

Collapse
 
shravan1908 profile image
Shravan

Neat! I also built a URL shortener and a terminal client recently, using Vercel but with a Python server and the CLI in NodeJS.

Check it out: github.com/shravanasati/titan-url

Collapse
 
sourabpramanik profile image
Sourab Pramanik • Edited

Cool one I checked it but, mine is different than what you have.

  • I have created a CLI to manage the links,
  • there is no web interface only CLI
  • you do not need to use any domain specified by me( in yours I have to use your domain https://titanurl.vercel.app for any links I will generate)
  • You will have your own database so the chances of conflict in near 0 (I don't have to use your database)
  • You can use multiple domains and group them
  • You will have complete control over the links you generate
  • Less prone to data losses and high availability
Collapse
 
shravan1908 profile image
Shravan

self-hosting is cool and all, but I doubt many people do that (only tech geeks). most people want to use a centralized server.

Thread Thread
 
sourabpramanik profile image
Sourab Pramanik

Self-hosting is a new way to build things out and everybody knows that and demands it.

Now for those who are not "tech geeks" I don't assume they will be reading Dev.to blogs if they don't have any clue or interest in tech at all, Right? This place is for people like you and me.

However, if I have to build a production-grade application it will be better than this but I will still prefer self-hosting even if I have to teach people how to use it.

Thread Thread
 
shravan1908 profile image
Shravan

haha you make good points