Question

I try to make soap-server with node.js using node-soap. I have wsdl like

<definitions name="HelloService"
   targetNamespace="http://www.examples.com/wsdl/HelloService.wsdl"
   xmlns="http://schemas.xmlsoap.org/wsdl/"
   xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
   xmlns:tns="http://www.examples.com/wsdl/HelloService.wsdl"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema">

   <message name="SayHelloRequest">
    <part name="firstName" type="xsd:string"/>
   </message>
   <message name="SayHelloResponse">
    <part name="greeting" type="xsd:string"/>
   </message>

   <portType name="Hello_PortType">
    <operation name="sayHello">
       <input message="tns:SayHelloRequest"/>
       <output message="tns:SayHelloResponse"/>
    </operation>
   </portType>

   <binding name="Hello_Binding" type="tns:Hello_PortType">
   <soap:binding style="rpc"
    transport="http://schemas.xmlsoap.org/soap/http"/>
   <operation name="sayHello">
    <soap:operation soapAction="sayHello"/>
    <input>
       <soap:body
        encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
        namespace="urn:examples:helloservice"
        use="encoded"/>
    </input>
    <output>
       <soap:body
        encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
        namespace="urn:examples:helloservice"
        use="encoded"/>
    </output>
   </operation>
   </binding>

   <service name="Hello_Service">
    <documentation>WSDL File for HelloService</documentation>
    <port binding="tns:Hello_Binding" name="Hello_Port">
       <soap:address
        location="http://localhost:8000/wsdl">
    </port>
   </service>
</definitions>

and my code

var http = require('http');
var soap = require('soap');
var helloService = {
  Hello_Service: {
    Hello_Port: {
      SayHelloRequest: function(args) {
        return {
          firstName: args.name
        };
      }
    }
  }
}
var xml = require('fs').readFileSync('HelloService.wsdl', 'utf8'),
      server = http.createServer(function(request,response) {
          response.end("404: Not Found: "+request.url)
      });
server.listen(8000);
soap.listen(server, '/wsdl', helloService, xml);

and I put them in same directory but got error

/nodejs_ws_demo/node_modules/soap/lib/wsdl.js:937 throw new Error(p.getError()); ^ Error: mismatched tag

How do I fix it.

Was it helpful?

Solution 2

There is an error in your wsdl file. soap tag is not closed.

<soap:address
        location="http://localhost:8000/wsdl"/>

OTHER TIPS

in addition to vinayr's answer, change the function to

var helloService = {
  Hello_Service: {
    Hello_Port: {
      sayHello: function(args) {
        return {
          greeting: "Hello!!!"
        };
      }
    }
  }
}

fix this in your code (method name and output parameter in your code is wrong).

sayHello is a soapAction in wsdl file:

<soap:operation soapAction="sayHello"/>

OP's code returns:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://www.examples.com/wsdl/HelloService.wsdl">
   <soap:Body>
      <soap:Fault>
         <soap:Code>
            <soap:Value>SOAP-ENV:Server</soap:Value>
            <soap:Subcode>
               <soap:value>InternalServerError</soap:value>
            </soap:Subcode>
         </soap:Code>
         <soap:Reason>
            <soap:Text>TypeError: method is not a function</soap:Text>
         </soap:Reason>
      </soap:Fault>
   </soap:Body>
</soap:Envelope>

Just for newbies the same as I am with Node.js...

Add the JS code to index.js and run npm init -y followed by npm install soap -s.

I'd suggest also to add a callback to soap.listen like this:

soap.listen(server, '/wsdl', helloService, xml, function() {
    console.log('server initialized');
});

Testing

if you want to test (e.g using SoapUI), WSDL is available on http://localhost:8000/wsdl?wsdl)

Request

(generated by SoapUI)

<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:examples:helloservice">
   <soapenv:Header/>
   <soapenv:Body>
      <urn:sayHello soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
         <firstName xsi:type="xsd:string">Betlista</firstName>
      </urn:sayHello>
   </soapenv:Body>
</soapenv:Envelope>

Response

If implementation changed to

  sayHello: function(args) {
    console.log("%j", args);
    return {
      greeting: "Hello " + args.firstName.$value + "!!!"
    };
  }
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://www.examples.com/wsdl/HelloService.wsdl">
   <soap:Body>
      <tns:sayHelloResponse>
         <tns:greeting>Hello Betlista!!!</tns:greeting>
      </tns:sayHelloResponse>
   </soap:Body>
</soap:Envelope>

log

$ node .
server initialized
args: {"attributes":{"soapenv:encodingStyle":"http://schemas.xmlsoap.org/soap/encoding/"},"firstName":{"attributes":{"xsi:type":"xsd:string"},"$value":"Betlista"}}

so in args we received

{
    "attributes": {
        "soapenv:encodingStyle": "http://schemas.xmlsoap.org/soap/encoding/"
    },
    "firstName": {
        "attributes": {
            "xsi:type": "xsd:string"
        },
        "$value": "Betlista"
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top