Building the Amazon Order Application
The first application that I built off of the prototype WMS Acquisition web service was the Amazon Order application. As I've explained in my basic overview of the Platform prototype application, the purpose of the Amazon application was to take an existing WMS order and send that order to Amazon, creating a shopping cart.
The first thing that the application does is generate a form screen which allows the user to input and existing WMS Acquisitions Purchase Order number.
Then the application take the purchase order number submitted and looks it up in WMS. If it finds a matching purchase order number then it displays the basic purchase order information: Order Number, Title, Vendor, Order Date.
The application then loops through the items on the order and attempts to find price and availability from Amazon. Because Amazon's API only let's you lookup things by ASIN or ISBN, it tries the each ISBN successively in the WorldCat record until it finds a match in Amazon. The application then builds a table of the order items: Title, OCLC Number, Availability, Price. The able has checkboxes that allows a user to remove any items that are not available from Amazon from the order. A "Place Order" button is only displayed if all the order items are available via Amazon.
When a user clicks the Place Order button, the application retrieves the order information from WMS and builds an Amazon cart containing all the items from the order. The user is presented with an updated order with a status of "SUBMITTED" and a link to the Amazon cart.
Building this applications presented a number of challenges. The first of them was the fact that Amazon uses a fairly complicated system for authentication. To make working with the Amazon API simpler, I decided to use the Zend framework which has a set of functions for dealing with the Amazon API. Additionally, the class didn't turn out to be as robust as I hoped. First, the Zend Amazon Classes doesn't have Cart building capabilities. As a result I ended up having to code calls to Amazon by hand for the cart creation. Second, the classes handling of Amazon error messages is very limited. In fact the only error message it handles is "AWS.ECommerceService.NoExactMatches". This caused it to throw Zend exceptions in circumstances when it should just return and empty object because a match isn't found: specifically the AWS.ECommerceService.ItemNotAccessible and AWS.InvalidParameterValue errors. To deal with this I altered my local version of the Zend Class to include the handing for the additional errors which solved the problem.
Looking back I'm not sure I would have chosen to use the Zend Amazon Class. If I did I would have certainly create my own class that extended it to add the additional error handling and also the Cart functions.
The second challenge this application presented was updating order information: item price, order status. and removing items from the order. Ironically, because of the REST nature of the service removing items from the order was the easiest of these tasks to perform. I just simply performed a DELETE on the url which represented the item I wanted to remove from the other.
Updating the order or order item information proved to be more of a challenge. This required pulling the order or order item document down as a JSON object. Deserializing it into an array. Updating the necessary field in the array, reserializing it as JSON and POSTing it back to the appropriate URL. Luckily Zend has a JSON class that encodes and decodes JSON which made that fairly simple.
The third challenge with this app was creating the Amazon cart for very large orders. This is because the write portions of the service like CartCreate and CartAdd aren't truly a REST API but rather RESTful. What I mean by this that they don't use POST or PUT. Instead, these interactions are transactions and handled completely over the query string. So you have to pass a parameter that tells the system what action you're taking, and then send all the appropriate data to complete the transaction in the query string. This may not seem like a big deal, but it has a fatal flaw. Only so much data can be passed via the query string.
You're probably still might be wondering why is this bad. Well if you want to create a cart with certain items in it, you have to pass the ASIN and the Quantity for every time in the query string. This might not be a big deal if you're only creating a cart with 5-7 items. You can do this all with one CartCreate. But the more items you want to put in the cart, the more data you have to send over the query string. With Amazon it seems like you can only put about 40 items in a cart at once. This means if you're thinking ahead, then you have to break up your cart creation into a multiple step process. The first step is to do a request to create the cart (CartCreate) and you have to put something in it. You can't create an empty cart. The next step is to add the other items to the cart. Which is a sequence requesst adds things to the cart (CartAdd). This adds an additional level of complexity to the code. I personallty find this disatisfying. As a result the current version of the app only handle orders with a small number of items. I need to go back and rewrite my code so the cart gets created in the two step fashion.
All and all I'm pretty happy with how the application turned out. I'd really like if there was slightly more Amazon integration which would allow me to place the order completely and get back and order number that I could put into WMS. But I think this application is a huge step in the right direction.
Senior Product Analyst