Problem
- You're faced with the task of making a SOAP request in Javascript.
- The recommended NPM packages for SOAP requests are unfamiliar and don't work easily.
Solution
Use a tool you're familiar with, such as axios
.
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', // These headers were taken from a successful request using the desktop application `SOAPUI`
'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
There are multiple packages available to create XMLs from, and parse XMLs to, Javascript objects. I use a combination of xml2js
& xmlbuilder
.
xmlbuilder
for creatingxml2js
for parsing
Here's how you can create an 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();
N.B. Find more about the specific syntax at https://www.npmjs.com/package/xmlbuilder
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', // These headers were taken from a successful request using the desktop application `SOAPUI`
'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, feel free to send me a tip via the Brave Browser.