Most of us interact with REST APIs on a regular basis, but from time-to-time we need to interact with SOAP APIs as well. For those of us with less exposure to SOAP, REST APIs are like the Shire and SOAP APIs are a little like Mordor. They are dark and scary and full or orcs.
It might help if you already understand:
- Working with REST APIs
- Sending requests to an API
A SOAP message is not as bad as it looks. It looks a little scary if you haven’t seen it before, but we are going to break down into manageable parts.
SOAP APIs utilize a document called a WSDL which give us information about the structure of the SOAP message, among other information. The WSDL is not in the scope of this post, but you can read more… on the Internet.
A SOAP message has 4 main elements:
- Header (optional)
SOAP requests are written in XML. XML has an HTML-like syntax with opening and closing tags. The outermost part of a SOAP message is called the envelope and looks something like this:
The envelope is the root element of a SOAP message and may contain a header, but will always contain a body.
Now, the envelope needs to know some things about itself, so we’re are going to add some attributes. This is what a common envelope might look like:
xmlns stands for XML Namespace. It tells us a little about the structure of the message and the namespacing. The namespace should be defined in the WSDL, so check the API docs from the API provider. Here are some variations we might see, and each one is acceptable depending on the specific API:
As you can see the envelope may have variations in namespace from API to API, but there are many commonalities. Here is one more example we see commonly that contains an
You may notice the additional namespaces in this example. You don’t necessarily need to understand everything these do, as long as they are correct. Many APIs are unique and you will need to refer to the documentation to construct your SOAP envelope.
The second element in a SOAP message is the header. The header element is technically optional. Like HTTP headers they can be used to send a variety of information. The header might look like this:
In this example we are passing a created date and nonce. A created date is used to ensure the request is current and may trigger an error if the date or time has expired or is incorrectly formatted. A nonce is a one-time code that helps the API prevent the processing of duplicate requests.
The header is often used to send credentials and handle security. The following is an example of a fairly complicated security header. We won’t cover it piece by piece, but you may want to see if you can figure out what is happening:
If we break this down we can see some familiar parts. We can see that
wsu are namespaces. We can see that they are defined by
xmlns because we know that stands for XML namespace. We can also see that the attribute
xmlns:wsse points to a URL that contains data regarding the
wsse namespace. And we can identify other key words that we already know like username, password, nonce, and created.
We’ll leave the header and move on, but we can start to see that, like everything in programming, breaking down new concepts into small parts will help us figure it out.
The body of the request should be a little more accessible to us. It is similar to a REST/JSON body in that it contains the data specific to a request. If we were sending a request with data related to a customer, for example, the body would contain items such as first name, last name, address, etc. It could look something like this:
env:Body tag there is a namespace for the request, the customer, and the customer-specific data. Again, the body structure is defined in the WSDL. Often there are examples in the documentation that you can use as a reference.
Lastly, we have the fault. There isn’t a lot to know about the fault. Essentially it is a string that returns error messages.
This first line points to the SOAP schema that defines the fault. The second line contains a fault code. The third line contains the fault message. This error was returned because the
Created timestamp was formatted incorrectly (12 hour clock instead of 24 hour clock).
You can read more about sending SOAP request with Postman here.
Relevant excerpt from SOAP Requests with Postman:
- Remember that even if a specific
SOAPActionis not required by the API, the header may still be necessary for the request to work.
- If you are using a timestamp, be sure it meets the specs from the API docs. Check that it is set to GMT and on a 24 hour cycle (i.e. if it’s afternoon, it should read 15:30, not 3:30).
- Also, make sure the timestamp is current. Timestamps are used to ensure the request is current and the request may be denied if the timestamp is even a few minutes old.
- If you are using a nonce, make sure it is unique with each request.
- Check the SOAP message format.
- Ensure that the schema URLs are correct.
- 99% of my errors are typos and incorrect spelling.
We hope this helps.
Please feel free to leave kind comments, suggestions, corrections and alternate solutions!