Redefining an Endpoint






Redefining an Endpoint

Problem

The WSDL file defines an endpoint for the service, but you need to change it to another URL. This happens when the service has testing and production sites, or requires you to pass additional query arguments as part of the URL.

Solution

If you want the same endpoint for all requests, specify a new location to the constructor in the options array:

<?php
$options = array('location' => 'http://www.example.com/testing-endpoint');

$client = new SOAPClient('http://www.example.com/service.wsdl',
                         $options);
?>

If it changes from request to request, use the __soapCall( ) method to pass a request-specific location:

<?php
$client = new SOAPClient('http://www.example.com/service.wsdl');

$method = 'getTemp';
$args = array('94114');
$options = array('location' => 'http://www.example.com/endpoint?method=getTemp');

$request = $client->__soapCall($method, $args, $options);
?>

Discussion

In most cases, you never need to modify the endpoint specified in the WSDL. Most services have a singular fixed endpoint, so they put it in their WSDL and you're done.

However, some sites require you to modify the endpoint location depending on a number of conditions. For example, they have both testing and production sites. This is not an issue with read-only services, but when you can both read and write to a site, it's important to have a sandbox environment where you can test your code.

For simplicity, the site may only publish a single WSDL file that targets the production server by default, and require you to switch it to point at the testing server during development. In these cases, it's easiest to specify the new location as a one-time configuration option in the SOAPClient constructor:

<?php
$options = array('location' => 'http://www.example.com/testing-endpoint');

$client = new SOAPClient('http://www.example.com/service.wsdl',
                         $options);
?>

The SOAPClient object takes an array of options as its second parameter. When you set the location element, it will override what's in the WSDL and use that URL as the location for all requests.

This method works best when you need to hit against the same URL for all requests. However, sometimes the endpoint can vary from request to request. For example, you may need to put the method name or other information within the URL itself.

Placing data in the URL allows the service to more efficiently route the request because it doesn't need to parse the XML document before dispatching it. For example, a large web service could have one pool of machines to handle searches and another pool of machines to handle updates. It can process requests faster if it can hand off the SOAP request directly to the proper pool simply by examining the URL.

This requires you to modify each request on a one-off basis. Therefore, you cannot use SOAPClient's method overriding abstraction. Instead, you need to use the __soapCall( ) method directly, passing the method name, arguments, and options:

<?php
$client = new SOAPClient('http://www.example.com/service.wsdl');

$method = 'getTemp';
$args = array('94114');
$options = array('location' => 'http://www.example.com/endpoint?method=getTemp');

$request = $client->__soapCall($method, $args, $options);
?>

This code is equivalent to:

<?php
$client = new SOAPClient('http://www.example.com/service.wsdl');

$request = $client->getTemp('94114');
?>

However, it also changes the endpoint URL to point at http://www.example.com/endpoint?method=getTemp instead of the WSDL default.

To preserve the simple calling convention, subclass SOAPClient for your service and provide a custom __call( ) method:

<?php
class TemperatureService extends SOAPClient {
    public function __call($method, $args) {

        // Modify endpoint to include method name
        // Assumes consistent naming convention
        $location = "http://www.example.com/endpoint?method={$method}";
        $options = array('location' => $location);

        return $this->__soapCall($function, $args, array('location' => $location));
    }
}

$client = new TemperatureService('http://www.example.com/service.wsdl');

$request = $client->getTemp('94114');
?>



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows