SOAP Node.js

How to Perform SOAP Requests With Node.js

Featured, Javascript, Node JS, Trending

Hi All, As a developer we are very comfortable with REST API calls but we all faces problem when we need to make SOAP calls . Recently i have developed some trading modules with EZE team using SOAP request in Node.js and sharing the experience with you. Lets start,

What is SOAP?

SOAP stands for Simple Object Access Protocol. It exist before REST API calls . SOAP is XML based API, where a 3rd party provides you a WSDL file (Web Service Description Language) . This WSDL file contains XML schema and actions need to sent on the 3rd party server.

If you compare the same with REST, the 3rd party will provide you a API documentation.

Lets come direct to the topic,

How to connect SOAP with Node.js

There are a lot of NPM modules available to perform SOAP requests.

I personally used soap NPM module to make SOAP requests. Lets go step by step to see the process of making SOAP request to a 3rd party.

First install the npm module

npm i soap

Now to make a SOAP request a WSDL file is must. If you don’t have a WSDL file ask the 3rd party vendor to provide you the WSDL file.

Save this WSDL file in a place, i recommend you can use .env to configure WSDL files as you must need diffrent WSDL files for different environments . ie development, staging or production.

Once you saved the WSDL file, now you have to create a SOAP client using WSDL file.

import * as path from 'path';
import * as soap from 'soap';

const WSDL = path.join(__dirname, './../../../../wsdl', `${process.env.EZE_WSDL}`);

const wsdlOptions = { useEmptyTag: true };

soap.createClient(WSDL, wsdlOptions, (err: any, client: any) => {
           if (err) reject(err);

           console.log(client)
                    
     });
 })

Here in my code i have used some wsdl options which are as follows

  • useEmptyTag : option causes tags with no contents to use the <Tag /> format instead.

Once you have created the client you can now use describe method to view the XML based WSDL file in JSON format and you can easily list the functions you need to use

app.get('/describe', function (req, res) {
    soap.createClient(url, (err, client) => {
        res.send(client.describe());
    });
});

The createClient method is used to create client object on wsdl file. Now you can use any wsdl function inside the createClient method as shown below.

let params = {

    'WebAuthenticationDetail': {
        'UserCredential': {
            'Key': "test", //Your Key given by FedEx
            'Password': "test" //Your Password given by FedEx
        }
    },
    'ClientDetail': {
        AccountNumber: "test", //Your Account Number given by FedEx
        MeterNumber: "test" //Your Meter Number given by FedEx
    },
    'Version': {
        'ServiceId': 'crs',
        'Major': '20', 
        'Intermediate': '0',
        'Minor': '0'
    },
    'ReturnTransitAndCommit': true,
    'RequestedShipment': {
        'ShipTimestamp': new Date(date.getTime() + (24*60*60*1000)).toISOString(),
        'DropoffType': 'REGULAR_PICKUP',
        'ServiceType': 'STANDARD_OVERNIGHT',
        'PackagingType': 'YOUR_PACKAGING',
        'TotalWeight': {
            'Units': 'LB',
            'Value': "10"
        },
        'Shipper': {
            'Contact': {
                'CompanyName': 'Company Name',
                'PhoneNumber': '5555555555'
            },
            'Address': {
                'StreetLines': [
                'Address Line 1'
                ],
                'City': 'Collierville',
                'StateOrProvinceCode': 'TN',
                'PostalCode': '38017',
                'CountryCode': 'US'
            }
        },
        'Recipient': {
            'Contact': {
                'PersonName': 'Recipient Name',
                'PhoneNumber': '5555555555'
            },
            'Address': {
                'StreetLines': [
                'Address Line 1'
                ],
                'City': 'Charlotte',
                'StateOrProvinceCode': 'NC',
                'PostalCode': '28202',
                'CountryCode': 'US'
            }
        },
        'ShippingChargesPayment': {
            'PaymentType': 'SENDER',
            'Payor': {
                'ResponsibleParty': {
                    'AccountNumber': "test" //Your Account Number given by FedEx
                }
            }
        },
        'RateRequestTypes': 'LIST',
        'PackageCount': '1',
        'RequestedPackageLineItems': {
            'GroupPackageCount': 1,
            'Weight': {
                'Units': 'LB',
                'Value': "10"
            },
            'Dimensions': {
                'Length': "4",
                'Width': "6",
                'Height': "10",
                'Units': "IN"
            }
        }
    }

};


app.get('/rate', function (req, res) {
    soap.createClient(url, function (err, client) {
        client.getRates(params, function (err, result) {
            res.json(result);
        });
    });
});

Sometimes to shorthand the WSDL file, it consist of contract urls in place of whole contract inside it. This is called XML in envelope and in this case the below code comes into action.

soap.createClient(WSDL, wsdlOptions, (err: any, client: any) => {
                    if (err) reject(err);

                    client.wsdl.definitions.xmlns.q6 = 'http://schemas.datacontract.org/2004/07/Eze.Common.Integration'
                    client.wsdl.definitions.xmlns.tns = 'http://tempuri.org/'
                    client.wsdl.definitions.xmlns.arr = 'http://schemas.microsoft.com/2003/10/Serialization/Arrays'
                    client.wsdl.xmlnsInEnvelope = client.wsdl._xmlnsMap();
                    client.RetrieveTrade(tradeParams, function (err: any, result: any) {
                        if (err) reject(err);

                        //console.log('last request: ', client.lastRequest) // <-- here
                        resolve(result);
                    });
                })

Additionally to test and debug the SOAP request you can download and use SOAP UI .

Leave a Reply