The purpose of the Alibris application is to allow a library to upload a tab seperated file of titles available in a particular topic area from Alibris, see which titles the library does not own, and then select titles for purchase. The first thing the application does is generate a form which allows a user to input their library's OCLC symbol and upload a tab seperated (TSV) file to the server

The application takes the TSV file and places it on the server. Then it loops through each of the lines in the TSV file to extract basic metadata about the item to check to see if the library owns the item. Using WorldCat Search API, for each item the application performs a search for library holdings based on the item's ISBN and the library's OCLC symbol. If it finds a match then the item is ignored. It it does not find a match then it performs an SRU search for an exact match of the title limited to the library's OCLC symbol. If it doesn't find a match then it uses the metadata to retrieve a single MARC bibliographic record for the item and extracts metadata such as the OCLC Number from this. It then presents the user with a table of all the items from the TSV file which the library does not own and for which a matching WorldCat records could be located.

The user can then check off the items which they wish to purchase and click the "Place Order" button.

The application then performs and AJAX action using the JQuery library which gathers data from the form and page and builds a JSON object of OCLC Numbers, and prices which is sent to a seperate PHP script that processes this and interacts with the prototype Acquisitions web service. The PHP script creates a JSON object that represents a new order and PUTs this to the Acquisition web service which creates a new order. The script retrieves the ID of the new order and then loops through all the items to be added to the order and creates a JSON object for each and PUTs it to url for the items in the newly created order. This adds each item to the order. When this is successfully completed the PHP script sends back a JSON object containing a success message and an HTML list of all the order items. The original application page displays a dialog window created with JQuery-UI that shows the order was successfully created and all the items that are part of the order.

Ideally we'd like this application to also send the order information to Alibris as well. However we haven't worked out the best way to make this happen yet. Alibris doesn't have a public order API. However, they do have some business to business web services that might allow us to create an order within their system but we haven't had a chance to work with that yet. Alternatively, we could create a tab or comma seperated file of all the items on the order and send this as an email. As of yet we haven't determined which of these approaches is the best fit.
This particular application presented the most challenges of all the applications I built. One aspect of this was it was the first application I built. Another was the fact that it doesn't use an external web service for its initial data. Instead it requires a spreadsheet which conforms to a specific format be uploaded. This is a major usability obstacle because user of the application have to make sure that the item uploaded conforms to the appropriate format. Otherwise the application will fail.
Additionally, having to upload the file to an actual server requires that the server be appropriately configured to allow the application to create files on it. This particular configuration might be a serious hurdle to libraries wanting to implement this script. I considering using something like GoogleDocs as a holding area for these files but discarded that idea due to privacy concerns and the need to have a Google account. Currently, I'm wondering if load the files into a NoSQL database might be a possible solution.
Another issue with this application was the performance and speed of using WorldCat Search API to see if library held a particular item. I spent a lot of time thinking about what the most efficient way would be to check this for a large group of items. Basically it boiled down to two possible approaches:
While the second approach seemed like it would be potentially speedier and reduce load of WorldCat Search API, it also seemed the more challenging to work with. This is because this type of search would get me records for items that the library already owns and I need items that the library doesn't own. As a result I decided to go with the first approach and basically check for each item to see if the library had holdings. For a large dataset this is painfully slow. I'd like to improve this but haven't had time to consider way to optimize performance.
The final challenge that this application presented was interacting with the prototype acquisitions web service to create the order. Working with a REST service that was capable of performing write operations was new for me. I had to use HTTP methods and headers as part of my code. This meant that I couldn't use older code that used the SimpleXML PHP library. I could've simply switched to using PHP CURL. However, I decide that the syntax for PHP CURL was more convoluted than I liked. The result was I ended up using the Zend Framework to make all of my REST web service calls. The framework has a nice library that allows developers to take advantage of all the bells and whistles of HTTP including Headers and methods. Plus the syntax is object oriented which makes it slightly easier to both work with and teach from.
Another aspect of the order web service that was chellenging was the fact that the service required that it be sent a JSON representation of the new order structured in a particular way. I could have built this JSON in my Javascript but because the structure and the value of many of the files would be the same if I was using the service for a different application, I decided to abstract this and use a PHP page as a proxy for the web service instead. I didn't NEED to structure the code this way. I could have done the building of the JSON object and the request to the web service in pure Javascript because the service didn't require a WSKey when I was working with it. Long term though I realized that
So I chose to keep it as a seperate PHP page. The last challenge that this application created was dealing with the fact that the JSON have fields with strict possible values, which were unknown to me. A good example of this was the library location field which has to be set when an order is created. Although I ended up merely looking up the possible values of this field for my test library WMS instance and hard coding an appropriate one, the experience made me realize that it is important to think about the suite of services that a developer will need to perform a given task. Otherwise key tangential but necessary services will be missing and make the development process more cumbersome.
Even with all the challenges building this application was an extremely worthwhile experience because it allowed me to learn about using new types of services, working in a new framework, and how to collaborate with external partners.
The OCLC Developer Network supports the use of OCLC Web Services—a set of tools and APIs that expose data and services for WorldCat and our member libraries and partner institutions or companies. learn more »
© 2010 OCLC Domestic and international trademarks and/or service marks of OCLC Online Computer Library Center, Inc. and its affiliates
Comments
A couple of suggestions
This looks like an interesting application, with potential for small libraries. A few comments & suggestions for minor fixes, before it goes to production:
1) Why does the application run on the user's server, instead of on OCLC's? This seems like a service OCLC could offer. Would target users for this application have the technical expertise to install/maintain/secure it themselves?
2) The app asks for a TSV file. There should be a "help" link the user can click to learn about the format required (what columns, in what order).
3) Typo: should be "separated".
Thanks --Andy
Thanks for the comments and
Thanks for the comments and suggestions. I've tried to answer your questions below
The application is designed to run on a user's servers because it was built from the perspective of a developer in an individual library. The idea was to showcase what a developer in an individual library would be able to build and potentially share the code with others via something like Github. That being said I certainly will pass along to the groups that consider new products and services internally the idea that OCLC could offer a compare this spreadsheet of stuff with a library holdings service.
Yes, the app could have some sort of indication of how to format the TSV file. As what is being consumed is an Alibris specific format that they use with their customers, this didn't go into the original planning of the application and is kind of wrong for the application is originally conceptualized. It can't take any old TSV nor should it. It has to be a TSV representing Alibris' current inventory for a given subject area. Alibris sends these spreadsheets to libraries all the time and I didn't want to ask users who had a these proprietary spreadsheets to have to do much fiddling with them to use this app. As a result the app is meant to just deal with THAT kind of spreadsheet which has not just the book metadata but also the Alibris pricing, condition and inventory numbers. Ultimately the app needs all the Alibris specific data to get the job done and a more generalized TSV wouldn't have that information.
That being said, some potential refactoring is going on with this application right now. Some of that has to do with the fact that I'd like to provide a more generic, compare this spreadsheet of stuff with a given library's holdings application, which would potentially not need to have the data submitted with particular columns. Another possibility would be to fork the code and refactor it to provide a generic create an order from a TSV tool as well. A final option would be to build a application that consumes a file of metadata for items, goes out and provides pricing and availability information from several supplies and then lets the library staff person select what should be ordered. The beauty of this model is that the application could be designed to be smart enough to create seperate orders within WMS for each vendor being ordered from.
Ultimately, there are lots of possibility. My hope in creating this was to get people thinking about the possibilities that having these types of web services available presents and to demonstrate some practical applications of what could be built.