Monday, March 26, 2012

Chaining Multiple Webservices

OK, with the support of the very helpful moderators, I've successfully built several bridges to external web services, and I'm getting the results transformed into json for use on my page. So far so good. Now I've reached the point where the async nature of all of this is throwing up an obstacle. Here's the basics of what I'm trying to do:

    Call WebService1 which gives me a list of addresses.Call WebService2 for each address that returns the coordinates for the address.Pass an array of these coordinates to a mapping service to plot on a map.

So, I'm successfully calling WebService1, getting the results, and then looping through the results and passing each one to WebService2. The problem is that I don't want to do #3 until the loop is done, and I have all of my coordinates in my array. But since it is all asynchronous, I'm not sure how to know when to kick off #3. First of all, is it possible to handle this in the javascript?

If that's not possible, then I considered the concept of "Chaining Multiple Bridge Requests". Since, the return from WebService1 is a list of addresses, but the input for WebService2 is a single address, I assume that I couldn't "declaratively" chain the requests. Is that correct?

Assuming that I can't do that, then, is my best bet to "programatically" chain multiple bridge requests, where all of my looping through the WebService1 results is done in the code-behind of the WebService1 bridge?

Thanks again for the help.

Sure you can do this either thru Javascript or programatically chaining the bridges as well. Basically if you want to do this in Javascript, you simply need to use a special OnComplete handler for the second webservice which kicks off Webrequest #3. Your other option is just to do all 3 of these requests in one bridge, and chain them up on the server in the code-behind as you mentioned.

Something like:

OnCompleteWebService2Chain(results) {

// <package up results for webrequest 3>
MappingService.Plot(transformedResults, OnComplete3, ...

}

Or in your codebehind:

object results1 = BridgeHandler.Invoke(<webservice1.asbx>, new BridgeRequest(method1, args);
IDictionary args2 = TransformResults1IntoArgs2(results1)
object results2 = BridgeHandler.Invoke(<webservices2.asbx>, new BridgeRequest(method2, args2);
...etc

Hope that helps,
-Hao


Well, that didn't clear it up too much, but a friend of mine gave me some guidance. Here's basically how I handled it:

var totalResults = 0;var coordinates =new Array();function OnWebService1Complete(searchResults){ totalResults = searchResults.length;for (i=0; i < totalResults ; i++) {//Call WebService2 Yahoo.GeoCode.GetCoordinates({location : searchResults[i].Address}, OnWebService2Complete, OnTimeout, OnError); } }function OnWebService2Complete(results){//simplified for example coordinates.push(results);if (coordinates.length == totalResults) {//All coordinate results must be in the array //So it's safe to initialize the map map.SetBestMapView(); }}

No comments:

Post a Comment