Friday 6 September 2013

SOAP web service using NuSOAP

SOAP web service is based on SOAP request and SOAP response messages. NuSOAP is a SOAP library written in PHP language.

SOAP message:

SOAP message is in XML format. It can be generated and parsed in any programming languages. A barebone SOAP message looks like below:

<?xml version="1.0"?>
<soap:Envelope
 xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
 soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
 <soap:Header>
  ...
 </soap:Header>
 <soap:Body>
  ...
  <soap:Fault>
   ...
  </soap:Fault>
 </soap:Body>
</soap:Envelope>

So SOAP message is just XML message. It becomes SOAP message with the soap namespace. The soap:Envelope is mandatory, the soap:Header is not. The soap.Body contains the actual rpc message. The soap.Fault is optional.

The graph above shows the soap envelope.

Looking at SOAP request message below:

<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:test-soap-server">
<SOAP-ENV:Body><tns:getProd xmlns:tns="urn:test-soap-server"><category xsi:type="xsd:string">music</category></tns:getProd>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>


From above we can see, getProd is the name of the function that will be called for this request, category is the parameter passed to the function. The valus "tns" stand for this name space.

Looking at SOAP response message below:

<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body><ns1:getProdResponse xmlns:ns1="urn:test-soap-server"><return xsi:type="xsd:string">The Music Collection, Victor Strauss: Writing music the creative way</return></ns1:getProdResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>


From above we can see, the getProdResponse is the response element, return is the return value.

WSDL file:

WSDL stands for web service description language. It is XML file that records SOAP service metadata. The metadata describes the functions that are provided by the web service application.

The elements that forms the WSDL file.

<definitions>
 <types>
  ........
 </types>
 <message>
  <part></part>
 </message>
 <portType>
  .......
 </portType>
 <binding>
  ....
 </binding>
 <service>
  ....
 </service>
</definitions>

SOAP server:

Soap server with WSDL output, named it "test-soap-server.php"::

<?php
require_once "nusoap-0.9.5/lib/nusoap.php";

function getProd($category) {
    if ($category == "books") {
        return join(",", array(
            "The Music Collection,
            "Victor Strauss:",
            "Writing music the creative way"));
    }
    else {
            return "No products listed under that category";
    }
}

$server = new soap_server();

$server->configureWSDL("test-soap-server", "urn:test-soap-server");

//$server->register("getProd");

$server->register("getProd",
    array("category" => "xsd:string"),
    array("return" => "xsd:string"),
//array("category" => "tns:string"),
    //array("return" => "tns:string"),
    "urn:test-soap-server",
    "urn:test-soap-server#getProd",
    "rpc",
    "encoded",
    "Get a listing of products by category");

// Use the request to (try to) invoke the service
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);

//$server->service($HTTP_RAW_POST_DATA);
//$server->service('php://input');

?>

The configureWSDL() asks the server to generate the WSDL file.

SOAP client:

SOAP client that uses the WSDL file, named it "test-soap-client.php":

<?php
require_once "nusoap-0.9.5/lib/nusoap.php";
//$client = new nusoap_client("http://127.0.0.1/test-soap-server.php");
$client = new nusoap_client("http://127.0.0.1/test-soap-server.php?wsdl", true);

$error = $client->getError();
if ($error) {
    echo "<h2>Constructor error</h2><pre>" . $error . "</pre>";
}

$result = $client->call("getProd", array("category" => "books"));

if ($client->fault) {
    echo "<h2>Fault</h2><pre>";
    print_r($result);
    echo "</pre>";
}
else {
    $error = $client->getError();
    if ($error) {
        echo "<h2>Error</h2><pre>" . $error . "</pre>";
    }
    else {
        echo "<h2>Books</h2><pre>";
        echo $result;
        echo "</pre>";
    }
}

echo "<h2>Request</h2>";
echo "<pre>" . htmlspecialchars($client->request, ENT_QUOTES) . "</pre>";
echo "<h2>Response</h2>";
echo "<pre>" . htmlspecialchars($client->response, ENT_QUOTES) . "</pre>";
echo '<h2>Debug</h2>';
echo '<pre>' . htmlspecialchars($client->debug_str, ENT_QUOTES) . '</pre>';

?>

The call() will call the method available in the web service.

Using SOAP:

Now if you run the soap client in the browser, you can see the screen below:


No comments:

Post a Comment