Wednesday, December 14, 2005

Ruby on Rails and Amazon Web Services

As a web interface designer, it is important to always keep one's skills fresh and sharp. I've never learned anything from a class, and very little from books. I'm a learn by doing kinda guy, so I've assigned myself a project.

I've decided to redesign Amazon's interface more to my liking, and I'm going to do it on top of a Ruby on Rails web application. I'm playing in the Web 2.0 sandbox.

If this isn't scary/boring:

ruby, SOAP, REST, WSDL, wsdl2ruby, soap4r, web services, AWS, ECS 4.0, XML

then read on...

First, I did some wireframes to start exploring how I thought a better Amazon interface might behave. I'll talk about that later, this post is about programming.

I looked around and found a nice wrapper for Amazon Web Services (AWS), now known as E-Commerce Services (ECS) 4.0. Lucky for me, a hard working ruby programmer had created Ruby/Amazon:

Ruby/Amazon is a Ruby language library that allows programmatic access to the popular Amazon Web site via the REST (XML over HTTP).

Awesome, just what I was looking for. It was easy to create an amazon controller in rails and make a little search form that would return a response. Fun!

Except, Ruby/Amazon is based on version 3.0 of AWS. My plans call for some functionality from version 4.0. The latest version isn't backwards compatible, and Amazon has made it clear that 4.0 is where it's at - a ha, a challenge!

Was there an up-to-date wrapper for AWS? I couldn't find one. But then I noticed that Ruby/Amazon used REST. What about SOAP, instead? Amazon supports that, too, but no luck there, either. The only wrapper out there is Ruby/Amazon.

But wait! Amazon helpfully provides a WSDL file (Web Services Description Language). Ruby has support for WSDL in the SOAP4R package, specifically wsdl2ruby.rb.

The wsdl2ruby program does what the name says - it takes a WSDL file as input and generates a series of ruby files that build classes and methods for the given web service.

[soap4r folder]/bin/wsdl2ruby.rb --wsdl [WSDL URL] --type client --force

That created three files: default.rb, defaultDriver.rb, and AWSECommerceServiceClient.rb. In default.rb, you can see how all of the classes get built for the various methods offered by the service. Attributes are built in as nil, and you have to specify empty quotes when creating a new object.

For the ItemSearch class, the SearchIndex wasn't created, so I had to do that by hand. And when I tried to build a "request" object, it errored, so I shoved everything into the "shared" object.

Here's my request:

req ="","","","","","","","","","","","","","","","","","","keywords go here","","","","","","","","","","","","","","","","")
body ="","AWS ID Goes Here","crastinate-20","","","Blended",req,"")
puts obj.itemSearch(body)

Next, I'll put all this where my rails app can get to it and write a handler that can output the response.

I've learned so much just to get to the web services equivalent of "Hello World."