If you are looking for a little project to work on & practice your Ruby skills then you are in the right place.
Today I want to build a “link shortener” application together with you.
What’s a link shortener?
I’m sure you have seen them before…
These “short links” like:
http://t.co/eKBRm2tTUF
When you visit this URL you get redirected to the original URL.
But how does that work?
The idea is to map this code, eKBRm2tTUF
in the example, to the original URL on our database.
It’s a simple concept, but there are a few things we need to handle.
Like…
How do produce this code? How do you match it to the full URL?
So let’s get started!
First Steps
I’m going to be using Sinatra for this because it requires no setup at all, so we can get going right away.
And instead of a typical SQL database I’m also going to be doing something different.
Keep reading to find out what that is 🙂
Here’s the initial code:
require 'sinatra' get '/:url' do "The URL is #{params[:url]}" end get '/' do "Send a POST request to register a new URL." end post '/' do "New URL added: #{params[:url]}\n" end
This is a simple Sinatra app with 3 actions, or routes if you prefer.
We can visit our application & we will get the “Send a POST request” message.
How do we do that?
You can use a browser plugin like Postman.
But I like to use curl
for this kind of thing.
It’s a handy tool that you should be able to install in any Operating System & it will allow you to interact with your Sinatra app.
Sending a POST Request
If you are following along you should have your Sinatra app running & curl
installed on your machine.
Now you can send a POST request like this:
curl localhost:4567 --data "url=rubyguides.com" -X POST
This should print the “New URL added” message on your terminal.
Great!
The next step is to map this URL to a shorter URL.
Let’s see how we can do that.
Mapping URLs
For the mapping you could do it using a random string, using a hash function or using some kind of encoding.
Here’s one way to do it:
LETTERS = Array('a'..'z') def generate_short_url Array.new(6) { LETTERS.sample }.join end
In this case I’m going with a random string of 6 characters.
Watch the video if you want to see another way to do it.
This will give us the “short code” that we are going to use to map the original URL to the short URL.
What’s next?
We need to save this code somewhere so we can redirect users to the proper place.
Our “NoSQL” Database
For this project I just wanted to use a simple database.
And what’s simpler than just using files, right?
Ruby’s standard library includes this PStore class that will help us manage the data.
This is great for a small application like ours.
Here’s the code:
class ShortURL def self.save(code, original) store.transaction { |t| t[code] = original } end def self.read(code) store.transaction { |t| t[code] } end def self.store @store ||= PStore.new("short_urls.db") end end
There are a few things going on here.
First, we have this store
method to access our PStore
object.
Then we have the save
& read
methods.
You will notice that PStore
behaves like a hash. With the difference that every operation needs to happen inside a transaction block.
Now we can update our Sinatra app to use the ShortURL
class:
require 'sinatra' get '/:url' do redirect "http://" + ShortURL.read(params[:url]) end get '/' do "Send a POST request to register a new URL." end post '/' do ShortURL.save(generate_short_url, params[:url]) "New URL added: localhost:4567/#{generate_short_url}\n" end
And that’s it!
We now have a working link shortener.
Pro Tip: You can use the shotgun gem to auto-reload your Sinatra app when you make changes in your code.
There is still some work to do, like adding a form so we don’t have to use curl
to submit a new URL.
Showing some message if the URL is not in the database.
And checking for duplicates, so we don’t overwrite other URLs.
I will leave those as homework for you 🙂
Summary
You learned how to build a Link Shortener application using Ruby, Sinatra & PStore! You also learned how to send a POST request using the curl
http client.
Don’t forget to share this article with your friends so more people can learn.
It would have been great if yo had mentioned which files should we changes to, Its kinda ambiguous the blog post. People who haven’t used Sinatra like me are lost.
Sorry about that! Everything goes on the same file then you run it like a normal Ruby program 🙂
Also here is a video version of this article: https://www.youtube.com/watch?v=i8oRhu4SDzo