Dummy @ work

Rants and pains in software (with contributors)

WSDL Proxy – Making your WSDL application Ajax-portable

Posted by deroude on January 6, 2009

Ok, so you want to access a WSDL source and consume it in your web application, using Javascript. With a very nice Javascript SOAP Client available, everything looks peachy, safe and well documented. Except it uses Ajax, and inherently XHR (XML HTTP Request), which cannot reach cross domain. That’s a bugger, of course, because the whole point of WSDL and Web Services in general is to be available to any number of consumers far and wide, from granny to Mars. So, how do we deal with that?

One solution is to have PHP retrieve the results and pass them into Javascript in a simple, unparsed (or custom parsed) form, then interepret them in Javascript – meaning of course we cannot use the nice Javascript SOAP Client, or SOAP in general, and we are back to Stone Age, passing string messages and praying they don’t have any demonizing special characters in them.
Another possible solution would be to have a PHP proxy WSDL, that takes the target Service url, required method and parameters as its own parameters, retrieves the results and passes them back to whoever needs them. You can use NuSOAP, as well as some well directed pointers from Scott Nichol and the Wacky Labs, to whom I’d like to extend my warm thanks.
Having concentrated on this solution, here is the proxy code:

<?php
require_once('lib/nusoap.php');
$server=new soap_server;
$server->configureWSDL('proxywsdl', 'urn:proxywsdl');

$server->wsdl->addComplexType(
  'results',
  'complexType', 
  'array', 
  '', 
  'SOAP-ENC:Array', 
  array(),
  array(
    array('ref' => 'SOAP-ENC:arrayType', 
         'wsdl:arrayType' => 'xsd:string[]')
  ),
  'xsd:string'
);

$server->register('proxy',                // method name
    array('url' => 'xsd:string','method'=>'xsd:string','params'=>'xsd:string'),        // input parameters
    array('result' => 'tns:results'),      // output parameters
    'urn:proxywsdl',                      // namespace
    'urn:proxywsdl#proxy',                // soapaction
    'rpc',                                // style
    'encoded',                            // use
    'Wraps and resends a wsdl package from an outside source - good for use with a localhost service client needing Ajax / XHR'            // documentation
);


function proxy($url,$method,$params) 
{
    $client = new soapclient($url, true);
    $err = $client->getError();
    if ($err) {
      return "Cannot connect to URL";
    }
    $result = $client->call($method,make_array($params));
    if ($client->fault) {
      return "Web service unavailable";
    } 
    else {
      $err = $client->getError();
      if ($err) {
          return $err;          
      } 
      else {
          return $result;
      }
    }
}

function make_array($p)
{
  $ret=array();
  $raw=split(',',$p);
  foreach ($raw as $par)
  {
    $unit=split(':',$par);
    $ret[$unit[0]]=$unit[1];
  }
  return $ret;
}

$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);
?>

And this is how you call it from an application (in PHP, but you can use javascript now, of course):

client->call('proxy',array('url'=>'https://127.0.0.1:8443/testWS/wsdl/wsSource.wsdl','method'=>'testDB','params'=>'name:cf_2009'));

The immediate rant I would have is that the parameters are passed to the proxy as a string, of the form:

param_name1:param_value1,param_name2:param_value2

which is not elegant and could lead to trouble, since there you don’t have a native way to check (and catch) validity errors. You can do that manually of course, in the make_array function. A second issue is that you cannot pass complex type parameters (but that is a rather rare occurence anyway).
The trouble is, at the point where you register the proxy Service, you have no idea of the types and count of parameters you will receive, so you cannot dynamically modify it (and it would be utterly unhealthy to do that, as well). Think of it as similar to the way you pass parameters via GET to a PHP page šŸ˜› . TODO – a workaround this.

Advertisements

One Response to “WSDL Proxy – Making your WSDL application Ajax-portable”

  1. […] more from the original source: WSDL Proxy – Making your WSDL application Ajax-portable Related ArticlesBookmarksTags PHP Development Tools – Keeping it Simple and Mostly Fre If […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

 
%d bloggers like this: