amazon-product-advertising-api

Introduction

A nice rubyish interface to the Amazon Product Advertising API, formerly known as the Associates Web Service and before that the Amazon E-Commerce Service.

The basic design philosophy is the ‘Principle of least surprise’, so it’s:

  • a dsl that should feel familiar to ruby folk.

  • structured generally like the API.

Prerequisites

It’s assumed you’re reasonably familiar with Ruby as a language, and the typical coding patterns and styles employed by the community.

It’s also assumed that you’re familiar with the API. If not go RTFM for a bit, it’s all pretty straight forward.

Overview

As mentioned before, the idea behind this is to model the API so that once you’re familiar with this library and the API, you’ll find this an easy way to navigate around it. You should then be able to just refer to the lists of Operations, Response Groups and Response Elements in the appendices for all you need to know.

You initiate requests by instantiating classes representing api Operations and named the same way, i.e. ItemSearch, ItemLookup, etc. The request parameters are represented by attributes on those objects and can be manipulated as you wish. If a parameter is required it’ll be required or defaulted on initialization, but everywhere else we defer to the defaults provided by the api.

Once setup, you call ‘run’ on the operation which will send the request and return a response object (and after that also available as operation.response).

The response has a bit less structure than the request operations. There is no representation for Response Groups as beyond one level deep there is no clear pattern for how returned XML is structured (at least not without going down the route trying to define custom handling for each of them). So, instead we group the Operations into broad groups which return the same collections of data. ItemSearch, ItemLookup and SimilarityLookup all return a Items container element with one or more Item tag in it, etc.

Everything beyond one level deep is done with a recursive sweep instantiating Element objects as we go.

Things to know

  • Amazon uses a lot of Camel case in their XML, but to suit Ruby / Rails conventions attributes, etc are converted to underscore style.

  • One gotcha - Response Elements can either be a simple value or a container with more elements inside. We recognise this situation by simply comparing the parent and child names (plural parent, singular child) though that isn’t always the pattern so we also look for multiple children of the same name.

    That means that some situations might creep through and not work as expected. If the parent and child don’t follow the same naming convention and there is also only one child element you’d find the child would be defined as parent.child rather than parent.children.first.

    This is a bug and will have to be addressed (probably by making a list of container elements to check against).

Having problems?

After running the request uri, returned raw xml and hpricot data will be available in operation.raw_data and operation.hpricot_data which should tell you all you need to know about the response.

Test coverage

There aren’t any tests at the moment but I’ll try to add some.

For the most part there isn’t really all that much to test though as it’s all largely just making http requests, however the XML parsing is quite convoluted so some tests would be good there to make sure the parsing is following the intended rules.

TODO

  • Implement the rest of the Operations (Cart*, Customer*, Help, List*, Seller*, Tag*, Transaction* and Vehicle*).

  • Implement batch and multiple operation requests, abstracted away from the user within the dsl.

  • Some sort of internal caching mechanism.

  • Ability to bind to different IP addresses, in order to circumvent API rate limiting.

Obtaining

The main repository is at github but there is also a rubyforge project.

Credits

Created by Jon Gilbraith, [email protected], while working with CompletelyNovel.

Contents of support.rb are basically taken and adapted from Rails’ ActiveSupport.