strong-soap: Node.js SOAP Client and Server
strong-soap provides a comprehensive Node.js module for interacting with SOAP web services, offering both client capabilities for invoking services and a mock-up server for testing. Currently at version 5.0.9, it maintains an active development pace with frequent patch and minor updates, typically on a monthly or bi-monthly schedule, and major versions released approximately annually to biennially, often aligning with Node.js version support. The library is built upon the `node-soap` module and distinguishes itself by supporting both RPC and Document styles, as well as SOAP 1.1 and 1.2 Faults. It includes utility APIs for converting XML to JSON and vice versa, describing WSDL documents, and handling both synchronous and asynchronous service method calls. A key feature is its built-in WS-Security support, specifically for UsernameToken and PasswordText encoding, enhancing its utility for enterprise integrations.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'output') at Server._executeMethod
cause This error occurs on the server side when the SOAP `Body` tag contains attributes (e.g., `soap:encodingStyle`), especially when using RPC style or non-default attribute keys.fixEnsure that your server-side implementation of `strong-soap` is compatible with attributes in the `Body` tag. Check for updates to `strong-soap` that address this. If unavailable, adjust the client to avoid sending attributes in the `Body` or modify the server's XML parsing logic if possible. -
Failed to create SOAP client: connect ETIMEDOUT
cause The client could not establish a TCP connection to the WSDL URL or the SOAP endpoint, likely due to network issues, incorrect URL, or firewall restrictions.fixVerify the WSDL URL and SOAP endpoint are correct and accessible from the environment where your Node.js application is running. Check network connectivity, firewall rules, and proxy settings if applicable. -
Cannot parse response
cause The SOAP service returned a response that `strong-soap` could not successfully parse, often due to malformed XML, unexpected content, or a non-SOAP response (e.g., HTML error page).fixInspect the raw `envelope` or `client.lastResponse` (if available in client events) to understand the actual response from the server. This can reveal if the service returned an error page, invalid XML, or an unexpected SOAP fault. Validate the service's WSDL and expected response structure. -
Using Strong-soap node module, It is not adding namespace to the attributes of the elements and due to which I am getting error -Invalid Attribute.
cause The library is not correctly attaching XML namespaces to attributes within elements in the outgoing SOAP request, leading to validation errors on the server side.fixReview the WSDL and the structure of your request arguments. Ensure that any custom headers or complex types requiring specific namespaces for attributes are correctly defined. This might require custom XML building or specific `wsdlOptions` to force namespace declarations.
Warnings
- breaking strong-soap dropped official support for Node.js 18 with the release of version 5.x. Projects running on Node.js 18 or older should use strong-soap v4.x or upgrade their Node.js environment to version 20 or higher.
- gotcha When using `WSSecurityCert` for X509 certificate-based security, the optional native dependency `ursa` (or its modern alternative `node-forge`) is required. Installation of `ursa` can sometimes fail on certain environments or Node.js versions due to native compilation requirements.
- gotcha Parsing large or complex WSDL files, especially from local paths, can sometimes cause `createClient` to hang indefinitely without returning an error or a client instance, making debugging difficult.
- gotcha The default parsing for XML attributes, values, and XML content uses keys like `$attributes`, `$value`, and `$xml`. If the SOAP service response uses different conventions or your application expects direct property access, this can lead to unexpected data structures.
Install
-
npm install strong-soap -
yarn add strong-soap -
pnpm add strong-soap
Imports
- soap
import strongSoap from 'strong-soap'; // 'strong-soap' exports a named 'soap' object, not a default.
import { soap } from 'strong-soap'; - WSSecurity
const WSSecurity = require('strong-soap').WSSecurity; // While functional, ESM named import is preferred for modern Node.js.import { WSSecurity } from 'strong-soap'; - WSSecurityCert
const WSSecurityCert = require('strong-soap').WSSecurityCert; // While functional, ESM named import is preferred for modern Node.js.import { WSSecurityCert } from 'strong-soap';
Quickstart
import { soap } from 'strong-soap';
import * as path from 'path';
// A public WSDL for a stock quote service
const wsdlUrl = 'http://www.webservicex.net/stockquote.asmx?WSDL';
async function getStockQuote(symbol) {
return new Promise((resolve, reject) => {
soap.createClient(wsdlUrl, {}, (err, client) => {
if (err) {
return reject(new Error(`Failed to create SOAP client: ${err.message}`));
}
// Describe the service to see available methods and their signatures
// console.log('Service Description:', client.describe());
// Invoke the GetQuote method. The method structure might be nested
// depending on the WSDL (e.g., client.Service.Port.Method)
const serviceMethod = client.StockQuote.StockQuoteSoap.GetQuote;
const requestArgs = {
symbol: symbol
};
serviceMethod(requestArgs, (err, result, envelope, soapHeader) => {
if (err) {
console.error('SOAP Request Error:', err.message);
// Log SOAP envelope for debugging if available
if (client.lastRequest) {
console.error('Last SOAP Request Envelope:\n', client.lastRequest);
}
return reject(err);
}
console.log(`Successfully fetched quote for ${symbol}`);
console.log('Result:', JSON.stringify(result, null, 2));
// console.log('Full SOAP Envelope:\n', envelope);
resolve(result);
});
});
});
}
(async () => {
try {
console.log('Fetching stock quote for IBM...');
await getStockQuote('IBM');
console.log('\nFetching stock quote for GOOG...');
await getStockQuote('GOOG');
} catch (error) {
console.error('Application Error:', error);
}
})();