Soap server using node js

Alejandro Mosquera picture Alejandro Mosquera · Apr 12, 2018 · Viewed 11.3k times · Source

I'm trying to create a soap service with node js. It seems like the most common to do this is to use this lib: https://www.npmjs.com/package/soap

They have this snippet:

var myService = {
  MyService: {
      MyPort: {
          MyFunction: function(args) {
              return {
                  name: args.name
              };
          },

          // This is how to define an asynchronous function.
          MyAsyncFunction: function(args, callback) {
              // do some work
              callback({
                  name: args.name
              });
          },

          // This is how to receive incoming headers
          HeadersAwareFunction: function(args, cb, headers) {
              return {
                  name: headers.Token
              };
          },

          // You can also inspect the original `req`
          reallyDetailedFunction: function(args, cb, headers, req) {
              console.log('SOAP `reallyDetailedFunction` request from ' + req.connection.remoteAddress);
              return {
                  name: headers.Token
              };
          }
      }
  }
 };

  var xml = require('fs').readFileSync('myservice.wsdl', 'utf8');

 //http server example
 var server = http.createServer(function(request,response) {
  response.end('404: Not Found: ' + request.url);
 });

 server.listen(8000);
 soap.listen(server, '/wsdl', myService, xml);

 //express server example
 var app = express();
 //body parser middleware are supported (optional)
 app.use(bodyParser.raw({type: function(){return true;}, limit: '5mb'}));
 app.listen(8001, function(){
     //Note: /wsdl route will be handled by soap module
    //and all other routes & middleware will continue to work
    soap.listen(app, '/wsdl', myService, xml);
});

my question is. Do I need generate this file: myservice.wsdl manually and later link it with the structure MyService?

Thanks

Answer

Terry Lennox picture Terry Lennox · Apr 12, 2018

Yes, you need to create the WSDL file yourself. I believe any of the available npm SOAP modules require this. There are various tools that can help you with WSDL generation, although one of the easiest ways is to simply start with a simple WSDL file. e.g. the file that corresponds to the MyFunction call as in your code above:

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

   <message name = "MyFunctionRequest">
      <part name = "testParam" type = "xsd:string"/>
   </message>
   <message name = "MyFunctionResponse">
      <part name = "status" type = "xsd:string"/>
   </message>
   <portType name = "MyPort">
      <operation name = "MyFunction">
         <input message = "tns:MyFunctionRequest"/>
         <output message = "tns:MyFunctionResponse"/>
      </operation>
   </portType>

   <binding name = "MyFunction_Binding" type = "tns:MyPort">
      <soap:binding style = "rpc"
         transport = "http://schemas.xmlsoap.org/soap/http"/>
      <operation name = "MyFunction">
         <soap:operation soapAction = "MyFunction"/>
         <input>
            <soap:body encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/" namespace = "urn:examples:MyService" use = "encoded"/>
         </input>
         <output>
            <soap:body encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/" namespace = "urn:examples:MyService" use = "encoded"/>
         </output>
      </operation>
   </binding>

   <service name = "MyService">
      <documentation>WSDL File for MyService</documentation>
      <port binding = "tns:MyFunction_Binding" name = "MyPort">
         <soap:address
            location = "http://www.examples.com/MyFunction/" />
      </port>
   </service>

</definitions>

You'd call using client code like this:

var soap = require('soap');
var url = 'http://localhost/wsdl?wsdl';
var args = {name: 'value'};
soap.createClient(url, function(err, client) {
  client.MyFunction(args, function(err, result) {
      console.log(result);
  });
});

Have a look at Client.describe() also, this is very useful and will return an object showing all methods the server supports.