A minimal node SOAP client and server implementation for Node.js applications
—
Server functionality for hosting SOAP web services on HTTP servers with automatic WSDL generation, request handling, and service method routing.
Create SOAP servers on existing HTTP server instances with service implementations and WSDL definitions.
/**
* Create SOAP server with individual parameters
* @param server - HTTP server instance (Node.js http.Server or Express app)
* @param path - URL path where WSDL will be served (e.g., '/wsdl')
* @param services - Service implementation object
* @param wsdl - WSDL content as string or file path
* @param callback - Optional completion callback
* @returns Server instance
*/
function listen(
server: any,
path: string,
services: IServices,
wsdl: string,
callback?: (err: any, res: any) => void
): Server;
/**
* Create SOAP server with options object
* @param server - HTTP server instance
* @param options - Server configuration options
* @returns Server instance
*/
function listen(
server: any,
options: IServerOptions
): Server;Usage Examples:
import { listen } from "soap";
import * as http from "http";
// Service implementation
const myService = {
MyService: {
MyServiceSoapPort: {
MyFunction: function(args, callback, headers, req) {
console.log('Received:', args);
callback({
name: args.name,
result: `Hello ${args.name}`
});
},
GetUserInfo: function(args, callback) {
// Simulate database lookup
const user = { id: args.userId, name: 'John Doe' };
callback({ user });
}
}
}
};
// Create HTTP server
const server = http.createServer();
// Attach SOAP service
const soapServer = listen(server, '/wsdl', myService, wsdlContent);
server.listen(8000, () => {
console.log('SOAP server listening on port 8000');
console.log('WSDL available at http://localhost:8000/wsdl?wsdl');
});SOAP server class managing service routing and request processing.
/**
* SOAP Server class for hosting web services
* Extends EventEmitter for request/response monitoring
*/
class Server extends EventEmitter {
/** URL path where the service is hosted */
path: string | RegExp;
/** Service implementations */
services: IServices;
/** Logging function for server operations */
log: (type: string, data: any, req: any) => any;
/** Function to authorize incoming connections */
authorizeConnection: (req: any, res?: any) => boolean;
/** Function to authenticate security credentials */
authenticate: (security: any, processAuthResult?: (result: boolean) => void, req?: any, obj?: any) => boolean | void | Promise<boolean>;
constructor(server: any, path: string | RegExp, services: IServices, wsdl: WSDL, options?: IServerOptions);
}Monitor incoming requests and header processing.
/**
* Server events for monitoring SOAP requests
*/
interface Server extends EventEmitter {
/** Emitted for every received messages */
on(event: 'request', listener: (request: any, methodName: string) => void): this;
/** Emitted when the SOAP Headers are not empty */
on(event: 'headers', listener: (headers: any, methodName: string) => void): this;
/** Emitted before sending SOAP response */
on(event: 'response', listener: (response: any, methodName: string) => void): this;
emit(event: 'request', request: any, methodName: string): boolean;
emit(event: 'headers', headers: any, methodName: string): boolean;
emit(event: 'response', headers: any, methodName: string): boolean;
}Usage Examples:
soapServer.on('request', (request, methodName) => {
console.log(`SOAP request for method: ${methodName}`);
console.log('Request body:', request.body);
});
soapServer.on('headers', (headers, methodName) => {
console.log(`Headers for ${methodName}:`, headers);
});
soapServer.on('response', (response, methodName) => {
console.log(`Sending response for method: ${methodName}`);
console.log('Response:', response);
});Manage SOAP headers and server configuration.
/**
* Add SOAP header to server responses
* @param soapHeader - Header object or XML string
* @param name - Header name (optional)
* @param namespace - Header namespace (optional)
* @param xmlns - XML namespace (optional)
* @returns Index of the added header
*/
addSoapHeader(soapHeader: any, name?: string, namespace?: any, xmlns?: string): number;
/**
* Modify existing SOAP header at specified index
* @param index - Index of header to modify
* @param soapHeader - New header object or XML string
* @param name - Header name (optional)
* @param namespace - Header namespace (optional)
* @param xmlns - XML namespace (optional)
*/
changeSoapHeader(index: any, soapHeader: any, name?: any, namespace?: any, xmlns?: any): void;
/**
* Get array of current SOAP headers
* @returns Array of current headers
*/
getSoapHeaders(): string[];
/**
* Clear all SOAP headers
*/
clearSoapHeaders(): void;Usage Examples:
// Add custom SOAP headers to responses
soapServer.addSoapHeader({
'ns1:ServerInfo': {
'ns1:Version': '1.0',
'ns1:Timestamp': new Date().toISOString()
}
});
// Clear headers when needed
soapServer.clearSoapHeaders();
### Service Implementation Structure
Define service methods that handle SOAP operations.
```typescript { .api }
/**
* Service structure matching WSDL service/port/operation hierarchy
*/
interface IServices {
[serviceName: string]: {
[portName: string]: {
[operationName: string]: ISoapServiceMethod;
};
};
}
/**
* SOAP service method handler signature
* @param args - Parsed arguments from SOAP request
* @param callback - Callback to send response (callback(responseObject))
* @param headers - SOAP headers from request
* @param req - Raw HTTP request object
*/
interface ISoapServiceMethod {
(
args: any,
callback: (response: any) => void,
headers?: any,
req?: any
): void;
}Usage Examples:
const calculatorService = {
CalculatorService: {
CalculatorSoapPort: {
Add: function(args, callback) {
const result = args.a + args.b;
callback({ result });
},
Subtract: function(args, callback) {
const result = args.a - args.b;
callback({ result });
},
// Method with error handling
Divide: function(args, callback) {
if (args.b === 0) {
const fault = {
Fault: {
faultcode: 'Server',
faultstring: 'Division by zero'
}
};
callback(fault);
return;
}
const result = args.a / args.b;
callback({ result });
},
// Method accessing request headers
SecureOperation: function(args, callback, headers, req) {
const authHeader = headers.Authorization;
if (!authHeader) {
callback({
Fault: {
faultcode: 'Client',
faultstring: 'Authorization required'
}
});
return;
}
callback({ status: 'success' });
}
}
}
};interface IServerOptions {
/** URL path for WSDL endpoint */
path: string;
/** Service implementations */
services: IServices;
/** WSDL content or file path */
wsdl: string;
/** Optional completion callback */
callback?: (err: any, res: any) => void;
/** Additional server configuration */
xml?: string;
/** URI path for service operations */
uri?: string;
/** Custom SOAP headers to include in responses */
headers?: any;
/** Enable request logging */
enableLogging?: boolean;
}The server automatically handles WSDL serving and operation routing based on the WSDL definition.
WSDL Access:
{serverPath}?wsdlExample WSDL Structure:
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://example.com/calculator"
xmlns:tns="http://example.com/calculator">
<service name="CalculatorService">
<port name="CalculatorSoapPort" binding="tns:CalculatorBinding">
<soap:address location="http://localhost:8000/calculator"/>
</port>
</service>
<portType name="CalculatorPortType">
<operation name="Add">
<input message="tns:AddRequest"/>
<output message="tns:AddResponse"/>
</operation>
</portType>
</definitions>The service implementation must match this hierarchy:
CalculatorServiceCalculatorSoapPortAddReturn SOAP faults for error conditions using standard fault structure.
/**
* SOAP fault response structure
*/
interface ISoapFaultResponse {
Fault: {
/** Fault code (Client, Server, etc.) */
faultcode: string;
/** Human-readable fault description */
faultstring: string;
/** Optional fault actor */
faultactor?: string;
/** Optional detailed fault information */
detail?: any;
};
}Include custom headers in SOAP responses.
// In service method
MyMethod: function(args, callback, headers, req) {
// Set custom response headers
req.res.setHeader('X-Custom-Header', 'value');
callback({ result: 'success' });
}SOAP servers work seamlessly with Express.js applications.
import express from 'express';
import { listen } from 'soap';
const app = express();
// Add SOAP service to Express app
const soapServer = listen(app, '/soap', services, wsdl);
// Regular Express routes can coexist
app.get('/health', (req, res) => {
res.json({ status: 'ok' });
});
app.listen(3000);Install with Tessl CLI
npx tessl i tessl/npm-soap