All Articles

Sending XML SOAP Requests With Axios


Problem

Summary

  • You’re faced with the task of making a SOAP request for the first time.
  • The recommended NPM packages for SOAP requests are unfamiliar and don’t seem to work easily.

Solution

Use Axios. It could be as simple as this:

const xml = '<your_xml></your_xml>'
const soapURL = 'https://...'

try {
  const res = await axios.post(soapURL, xml, {
    headers: {
      'Accept-Encoding': 'gzip,deflate',
      'Content-Type': 'text/xml;charset=UTF-8',
      'SOAPAction': 'provider_soap_request_type', // this may be required or not, depending on the wsdl setup
    },
  });
} catch (e) {
  // Handle e...
}

In this example:

  • The soapURL & SOAPAction are set by the endpoint provider
  • The xml is the string form of the xml required for the request

Handling XMLs in Javascript is fairly straight-forward. I use two separate packages for creating vs parsing, though xml2js can be used for both.

  • xmlbuilder for creating
  • xml2js for parsing

Here’s how you can create the xml using xmlbuilder:

const xml = xmlbuilder
  .begin()
  .ele({
    'soapenv:Envelope': {
      '@xmlns:soapenv': 'http://schemas.xmlsoap.org/soap/envelope/',
      '@xmlns:api': 'your_provider_soap_api',
      'soapenv:Header': {},
      'soapenv:Body': {
        'api:your_soap_api_endpoint': {
          sessionId: '1234-XYY',
          userId: 123,
          ...,
        },
      },
    },
  })
  .end();

The exact keys required inside the soapenv:Body object depends on the xml nodes you need for your request, but it should look fairly similar to the above.

You can pass the xml created by xmlBuilder as the xml argument in the axios code above.

And when you get the response…

const parsedResponseToJS = await xml2js.parseStringPromise(res.data, { explicitArray: false, ignoreAttrs: true });

parsedResponseToJS will be a JS object representation of the XML response, ready for you to validate and use in your code.

Here’s all that put together:

const buildXml = () => {
  return xmlbuilder
  .begin()
  .ele({
    'soapenv:Envelope': {
      '@xmlns:soapenv': 'http://schemas.xmlsoap.org/soap/envelope/',
      '@xmlns:api': 'your_provider_soap_api',
      'soapenv:Header': {},
      'soapenv:Body': {
        'api:your_soap_api_endpoint': {
          sessionId: '1234-XYY',
          userId: 123,
          ...,
        },
      },
    },
  })
  .end();
}

const xml = buildXml()
const soapURL = 'https:myurl.com'

const res = await axios.post(soapURL, xml, {
  headers: {
    'Accept-Encoding': 'gzip,deflate',
    'Content-Type': 'text/xml;charset=UTF-8',
    'SOAPAction': 'provider_soap_request_type', // this may be required or not, depending on the wsdl setup
  },
}).catch(e => {
  // Some error handling and logging
});

const parsedResponseToJS = await xml2js.parseStringPromise(res.data, { explicitArray: false, ignoreAttrs: true });

Problem Solved?

If you have any questions you’d like to ask me about this post, feel free to reach me on Twitter or Github.

If you found this post useful and would like to show you’re appreciation, explore the links in the sidebar :)