Building Mashup-Friendly Sites in Railsby Jack Herrington
So you are probably thinking to yourself, "Fine, I can use Ajax from my web page to get data from my web services interface and then put it into maps." Not true. Because of the security model in most of the browsers, a web page can only make an Ajax request to pages in the same domain. Have a look at Figure 1.
Figure 1. Getting to the proxied service
Let's say you have a web page and a Rails service located somewhere else that you want to get access to. (Actually, it doesn't have to be Rails, it can be anything, but I'll use Rails as an example.) As you see in Figure 1, the page itself cannot directly make a call to get the pages from the Rails service because it's hosted in a different domain. To make the call the page will have to go back to a proxy service located on a server in the same domain and have it make the request, then return the data.
This is why the widget sites, like Microsoft Live or iGoogle, all have proxies built into them: so that people can access their SOAP, XML/RPC, REST, or JSON interfaces without having to build a mashup-friendly interface.
In this article I'm going to take a page from the Google Maps playbook and show you how to build a web services interface that is mashup friendly, where the only tools you need to get to the data on your Rails server is Notepad and a browser, just like you see in Figure 2.
Figure 2. Building the easily mashupable interface
That way you can display data from your Rails service on blogs, and static HTML pages, and who knows whatever else from anywhere on the Web.
I've chosen Rails for this example for two reasons: first, it's cool and second, it's easy. What I'm doing here you could easily do in PHP, Java, .NET, or any web server technology. I'll start us out by creating the Rails site, and then I'll show you a progression of different transport mechanisms, starting with the familiar Ajax/XML pattern and ending with a mashup-friendly script tag transport mechanism.
Building the Rails Service
To demonstrate building a mashup-friendly web service I'll build a simple Rails application. The application will store a list of images along with description, title, and location in latitude and longitude. The Rails code to create the database is shown in Listing 1.Listing 1. The database definition
class CreatePhotos < ActiveRecord::Migration def self.up create_table :photos do |t| t.column :title, :string, :null => false t.column :description, :string, :null => false t.column :url, :string, :null => false t.column :latitude, :double, :null => false t.column :longitude, :double, :null => false end end def self.down drop_table :photos end end
Once the database is set up, we have to have a model to represent the individual photos. That model definition is shown in Listing 2.Listing 2. The Photo Model
class Photo < ActiveRecord::Base end
There isn't much to it. I could add some constraints, but the application itself isn't the point of this article. The interesting stuff starts in the controller, which is shown in Listing 3.Listing 3. The Photos Controller
At the top is the usual Rails scaffolding, which I will use to add some images into the database. The list of images I've entered into the database is shown in Figure 3.
Figure 3. The scaffolding with the list of images
It's the 'jscallback' method that makes the application mashup friendly. But in order to explain why, I need to start with the basic Ajax/XML pattern that we are familiar with.