The following article is part of a series, for more article in this series see Creating a URL Shortener in Rails 3.
URL shorteners are popular web applications. They take a very long URL and create a short URL which redirects you back to the long URL. At first that sounds silly, but if you've ever tried to post a link to a place on Google maps or an item on Amazon or Ebay to IRC or Twitter, you'll see just how necessary these are. Many services even implement their own URL shortening (Google and Youtube do this), it helps people share links to content on the service so this is a worthwhile feature to add to any web application.
Alice has a long URL she wants to send to Bob via Twitter. Twitter, being what it is, only allows 140 characters and the URL she wants to send is longer. Alice opens up the URL shortening web application, enters the long URL into a form and is given a URL like http://short.url/jd82jdk. Nice and short, easy to share, so she sends it to Bob. When Bob clicks on the link, the web application redirects his browser back to the long URL. This is a simple concept and is rather simple to implement in Ruby on Rails.
So let's think about the problem a bit more deeply. Firstly, what data for the model will we need? Every entry needs the original URL, as well as the short URL (or at least the last portion after the domain name). As a bare-bones solution, that's all you need. However, we'll add a useful feature: an optional short description. A normal URL gives you a clue as to what it's pointing to. The URL http://store.url/products/10 tells you the name of the site, that it's a page for a product and the ID for the product. Two of those pieces of information are useful, but the shortened URL of http://short.url/jdks8sj doesn't tell you anything.
We could allow the user to add a string describing the URL if they wish. So, the URL Alice sends to Bob could read http://short.url/jdks8sj/jacket-i-want instead. The URL is longer, but carries more information. (And in this example, the shortened URL is longer than the original URL, so it's kind of pointless). But if you think about it, the description doesn't actually have to be stored in the database. It's only there to annotate the link, it doesn't matter what it says at all. So the URL format is more like http://short.url/:id:/you-can-put-anything-you-want-here. So we won't even store that.
So in total that's 2 fields:
- original - The original URL.
- short - The short URL. This will be automatically generated in the model as a base36 encoding of the ID parameter (which all ActiveRecord objects automatically have). Base 36 uses numbers and letters.
What controllers will this need? Well, one, we'll call it Short, just like the model. It'll need only the scaffolded methods. The routing is a bit tricky here though. Only the root route will do anything useful. GET the root and it'll give you the form submission for creating a new short URL. POST (or, more accurately, PUT) the root and it'll create a new short URL from that form and give you the link. Any other route is interpreted as a short URL, but why? If I have a Short controller, why won't http://short.url/short do anything? Since we're using base 36, this is also a valid ID for a short URL. Eventually, someone will happen to create a short URL whose ID, when encoded in base 36, will be "short," and that URL will be inaccessible. So we'll be removing the resources statement from the routes.rb file and just making a few routes manually.
This all sounds great, but there are two things worth mentioning about URL shorteners in general. These aren't major issues, and are inherent to all URL shorteners, but they are worth thinking about.
URL shorteners break the web. The web is built on links. Site A links to Site B, this is why it's called "the web." What happens when (for example) bit.ly (a very popular site for shortening URLs) goes out of business and shuts down? All of those links are now dead. Many of the links ended up on more ephemeral media such as instant messages, IRC, twitter, Facebook, etc. No one is going to care that tweets they made 10 years ago now have dead links (what they were linking to is most likely gone anyway), but it is worth noting that this is an issue.
URL shorteners can also be used for deception. Say Carol is very careful what she clicks on. She sticks to her major sites, doesn't want to pick up any malware or anything like that. However, Bob has malware on his computer that sends a message with a shortened URL to Carol. Thinking it's an innocuous URL from Bob to a site she's familiar with, she clicks on it and is taken somewhere she doesn't want to go. The annotation feature described above is to remind and inform based on trust, it's not a security device in any way.
There are some things you can do about the second point though. Some URL shorteners let you preview the site before you visit it, or tells you the real URL before redirecting you there. But that is out of scope for this article.
We're Ready, Let's Do This
In part 2 of this series, we'll actually implement this.