Simple webservice with node-soap

16,162

Solution 1

As user672320 pointed out the reason client.js failed was because the format of the wsdl used was 'RPC/literal' but the style was set as 'document' rather than RPC.

In fact any one of five formats can be used for wsdl, each has a diferent format.

See Which style of WSDL should I use? for a discussion of which style to use.

Also, the example given is not complete.

See below for expanded version:

wsdl file:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="wscalc1" targetNamespace="http://localhost:8000/wscalc1" xmlns="http://localhost:8000/wscalc1" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <wsdl:message name="sumarRequest">
    <wsdl:part name="a" type="xs:string"/>
    <wsdl:part name="b" type="xs:string"/>
  </wsdl:message>
  <wsdl:message name="multiplicarRequest">
    <wsdl:part name="a" type="xs:string"/>
    <wsdl:part name="b" type="xs:string"/>
  </wsdl:message>
  <wsdl:message name="multiplicarResponse">
    <wsdl:part name="mulres" type="xs:string"/>
  </wsdl:message>
  <wsdl:message name="sumarResponse">
    <wsdl:part name="sumres" type="xs:string"/>
  </wsdl:message>
  <wsdl:portType name="calcP">
    <wsdl:operation name="sumar">
      <wsdl:input message="sumarRequest"/>
      <wsdl:output message="sumarResponse"/>
    </wsdl:operation>
    <wsdl:operation name="multiplicar">
      <wsdl:input message="multiplicarRequest"/>
      <wsdl:output message="multiplicarResponse"/>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="calcB" type="calcP">
    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="sumar">
      <soap:operation soapAction="sumar"/>
      <wsdl:input>
        <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="multiplicar">
      <soap:operation soapAction="multiplicar"/>
      <wsdl:input>
        <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="ws">
    <wsdl:port binding="calcB" name="calc">
      <soap:address location="http://localhost:8001/wscalc1"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

server.js:

/*jslint node: true */
"use strict";

var soap = require('soap');
var http = require('http');

var service = {
    ws: {
        calc: {
            sumar : function(args) {
                var n = 1*args.a + 1*args.b;
                return { sumres : n };
            },

            multiplicar : function(args) {
                var n = args.a * args.b;
                return { mulres : n };
            }
        }
    }
};

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

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

server.listen(8001);
soap.listen(server, '/wscalc1', service, xml);

client.js:

var soap = require('soap');
var url = 'http://localhost:8001/wscalc1?wsdl';

soap.createClient(url, function(err, client) {
    if (err) throw err;
    console.log(client.describe().ws.calc);
    client.multiplicar({a: 4,b: 3},function(err,res){
        if (err) throw err;
        console.log(res);
    });
    client.sumar({a: 4,b: 3},function(err,res){
        if (err) throw err;
        console.log(res);
    });
});

with that the code output is:

   { sumar:
   { input: { a: 'xs:string', b: 'xs:string' },
     output: { sumres: 'xs:string' } },
  multiplicar:
   { input: { a: 'xs:string', b: 'xs:string' },
     output: { mulres: 'xs:string' } } }
   { mulres: '12' }
   { sumres: '7' }

Solution 2

in the wsdl file what i change is the style from document to rpc trying to get antoher response using the client.js

What i receive is this output.

{ sumar: 
   { input: { a: 'xs:string', b: 'xs:string' },
     output: { res: 'xs:string' } },
  multiplicar: 
   { input: { a: 'xs:string', b: 'xs:string' },
     output: { res: 'xs:string' } } }
{ res: '2' }
Share:
16,162
Admin
Author by

Admin

Updated on July 26, 2022

Comments

  • Admin
    Admin almost 2 years

    I am trying to implement a simple web service using SOAP using Node Js and node-soap, but the client side seems to have problems using the server.

    assert.js:92
      throw new assert.AssertionError({
            ^
    AssertionError: invalid message definition for document style binding
    

    My wsdl file is:

    <?xml version="1.0" encoding="UTF-8"?>
    <wsdl:definitions name="wscalc1"
                      targetNamespace="http://localhost:8000/wscalc1"
                      xmlns="http://localhost:8000/wscalc1"
                      xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                      xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
                      xmlns:xs="http://www.w3.org/2001/XMLSchema"
                      xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
    
      <wsdl:message name="sumarRequest">
        <wsdl:part name="a" type="xs:string"></wsdl:part>
        <wsdl:part name="b" type="xs:string"></wsdl:part>
      </wsdl:message>
    
      <wsdl:message name="multiplicarRequest">
        <wsdl:part name="a" type="xs:string"></wsdl:part>
        <wsdl:part name="b" type="xs:string"></wsdl:part>
      </wsdl:message>
    
      <wsdl:message name="multiplicarResponse">
        <wsdl:part name="res" type="xs:string"></wsdl:part>
      </wsdl:message>
    
      <wsdl:message name="sumarResponse">
        <wsdl:part name="res" type="xs:string"></wsdl:part>
      </wsdl:message>
    
    
      <wsdl:portType name="calcP">
        <wsdl:operation name="sumar">
          <wsdl:input message="sumarRequest"></wsdl:input>
          <wsdl:output message="sumarResponse"></wsdl:output>
        </wsdl:operation>
    
        <wsdl:operation name="multiplicar">
          <wsdl:input message="multiplicarRequest"></wsdl:input>
          <wsdl:output message="multiplicarResponse"></wsdl:output>
        </wsdl:operation>
      </wsdl:portType>
    
      <wsdl:binding name="calcB" type="calcP">
        <soap:binding style="document" 
                      transport="http://schemas.xmlsoap.org/soap/http"/>
    
        <wsdl:operation name="sumar">
          <soap:operation soapAction="sumar"/>
          <wsdl:input>
            <soap:body use="literal" 
                       encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
          </wsdl:input>
          <wsdl:output>
            <soap:body use="literal" 
                       encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
          </wsdl:output>
        </wsdl:operation>
    
        <wsdl:operation name="multiplicar">
          <soap:operation soapAction="multiplicar"/>
          <wsdl:input>
            <soap:body use="literal" 
                       encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
          </wsdl:input>
          <wsdl:output>
            <soap:body use="literal" 
                       encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
          </wsdl:output>
        </wsdl:operation>
      </wsdl:binding>
    
      <wsdl:service name="ws">
        <wsdl:port name="calc" binding="calcB">
          <soap:address location="http://localhost:8000/wscalc1"/>
        </wsdl:port>
      </wsdl:service>
    </wsdl:definitions>
    

    server.js

    var soap = require('soap');
    var http = require('http');
    
    var service = {
        ws: {
            calc: {
                sumar : function(args) {
                    var n = args.a + args.b;
                    return { res : n };
                },
    
                multiplicar : function(args) {
                    var n = args.a * args.b;
                    return { res : n }
                }
            }
        }
    }
    
    var xml = require('fs').readFileSync('wscalc1.wsdl', 'utf8'),
    
    server = http.createServer(function(request,response) {
        response.end("404: Not Found: "+request.url)
    });
    
    server.listen(8000);
    soap.listen(server, '/wscalc1', service, xml);
    

    client.js

    var soap = require('soap');
    var url = 'http://localhost:8000/wscalc1?wsdl';
    soap.createClient(url, function(err, client) {
    
        if (err) throw err;
    
    
        console.log(client.describe().ws.calc);
    
        client.multiplicar({"a":"1","b":"2"},function(err,res){
            if (err) throw err;
    
            console.log(res);
        });
    });
    

    with that code the output is:

    { sumar: 
       { input: { a1: 'Request', b1: 'Request' },
         output: { res: 'Response' } },
      multiplicar: 
       { input: { a2: 'Request', b2: 'Request' },
         output: { res: 'Response' } } }
    
    assert.js:92
      throw new assert.AssertionError({
            ^
    AssertionError: invalid message definition for document style binding
    

    any help will be really appreciated