Using AWS and bit.ly to eliminate server state

Billr is an iPhone app I developed for helping to split the restaurant bill fairly at the end of the meal.

One feature I wanted to include was the ability to text message out a copy of the split bill. Then, a single person could pay for the whole tab and send out a copy of the bill to the others. Each person would then know how much to pay back to the person who paid. Unfortunately, the iOS SDK doesn’t provide a method for programmatically sending MMS messages. So I couldn’t attach a screenshot of the bill to a text message directly. This meant I would have to host the image somewhere, and send a URL to the image in a text message instead.

I could have easily uploaded the image to any number of services and sent a URL to where the image was being hosted. But I wanted the URLs to be on the billr.me domain, and to be able to include a link to download the app on the page. This was going to require I implement some server-side logic for serving the images.

But rather than roll my own complex server, I decided to utilize the work of other people to make my job easier and to reduce the amount of maintenance work I would have to perform. 

  1. Images are uploaded from the phone to Amazon S3 directly. I used the AWS SDK for iOS to make this easy.
  2. I wanted to generate short URLs for easier readability on the phone. So, I used a simple Objective-C API for bit.ly's URL shortening service. This meant I could offload the job of keeping track of short URL identifiers to the team at bit.ly, rather than maintaining that state myself.
  3. I needed a way to make billr.me/<bill_id> render the bit.ly image, along with a few links surrounding it. So, I modified my .htaccess file as follows:  The RewriteCond rules will prevent bills.php from being served if the request is for a real directory or real file that already exists on the server. The RewriteRule rule will strip any identifier billr.me/<id> and pass it as an argument to bills.php.
  4. Now, in bills.php, we can just render the bit.ly image, using the ‘id’ passed in as an argument. We want to make sure the bit.ly link resolves to an image being hosted in my S3 bucket (rather than, say, your pornography website). I’m using PHP-bitly to resolve the short URL to its expanded form. I then check to make sure it resolves to an image I own. If the URL is invalid or doesn’t resolve to an image hosted on my bucket, we display a 404 image in its place. 

Combining these four elements has allowed me to upload and serve images from the billr.me domain without maintaining a database. I’m hosting on https://www.nearlyfreespeech.net/ for pennies per month and never need to do any server maintenance.