Apr 1, 2009

jQuery web service proxy

Web Services, jQuery, JavaScript

A little while back I was looking for a nice convenient way of calling ASP .Net web services from JavaScript. I looked at the MS Ajax implementation, however I’m a little uncomfortable with the Script Manager and all the related plumbing. It’s just a little heavy for my taste, and I’m not a big fan of the auto generated web service proxy. I also wanted to keep the door open for porting my project to Mono and I wasn’t sure if those features have been ported yet (if they have, ping me). I looked at jQuery, Prototype and Scriptaculous and of those three I liked jQuery the best for the additional features the package offers. Right off the bat jQuery was pretty simple to use and set up, but a little too much typing for my taste. Here’s what I came up with:

   1:  (function($) { $.proxy = function(options) {
   2:          
   3:          /* Default .Net web service proxy options. */
   4:          var defaults = {
   5:              mode: "POST",
   6:              contentType: "application/json;charset=utf-8",
   7:              dataType: "json",
   8:              endPoint: "",
   9:              data: "",
  10:              success: {},
  11:              failure: {}
  12:          };
  13:          
  14:          /* Extend (or override) the defaults with any passed in options. I really like this extend feature. */
  15:          var options = $.extend(defaults, options);
  16:   
  17:          /* Make the ajax call using $.ajax() */
  18:          return $.ajax({
  19:              url: options.endPoint,
  20:              type: options.mode,
  21:              contentType: options.contentType,
  22:              dataType: options.dataType,
  23:              data: options.data,
  24:              success: options.success,
  25:              error: options.failure
  26:          });
  27:      };
  28:  })(jQuery);

This is a simple jQuery plug-in that encapsulate the details of calling ASP .Net web services. This is pretty sweet since now I can do something like this and avoid all that set-up work every time I need to call into the back-end:

   1:  Zanzibar = {}
   2:  Zanzibar.Web = {
   3:      LocationService: {
   4:          Get: function(options) {
   5:              $.extend(options, { endPoint: "http://localhost:60088/RPC/GeoLocation.asmx/Get" });
   6:              
   7:              return $.proxy(options);
   8:          }
   9:      }
  10:  }

This becomes my proxy now. I’m extending the options with the specific end point for the web method I need to call and the usage pattern for this becomes something like the following:

   1:  Zanzibar.Web.LocationService.Get({
   2:      data: "{ userId: 10001 }",
   3:      success: successCallback,
   4:      failure: errorCallback
   5:  });

This is great, because now all I need to worry about is the actual parameters I want to call my web service with, none of the setup work is needed up front anymore. Clearly other methods can be added and you can provide a really nice, rich wrapper for a web service this way. No complex inheritance, just some simple composition and extension of passed in parameters with some default settings. I really like the $.extend() function, comes in very handy for defaulting parameters and helping cut down on verbosity somewhat. Using that cool feature I can trim the code down but I still retain the power of customizing every aspect of my web service call if I need to.