Vladimir Dyuzhev, author of MockMotor

Vladimir Dyuzhev
MockMotor Creator

SOAP Attachments with MTOM/XOP

Switch MTOM/XOP on in the Response Attachments section.

What’s wrong with SWA?

Previously I described SOAP with Attachments (SWA) and how to use it in MockMotor.

SWA is still in use today, but another specification became the standard instead: MTOP/XOP. Why?

The main reason is that the attachments in SWA are not logically a part of the response. They are separate parts. From the code point of view that causes unnecessary efforts.

Consider this SWA pseudo-code:

Response resp = callReportsService();
Report report = readPayload(resp);
byte[] reportPDF = readAttachment(resp);

The report meta-data and the report itself (as a PDF) are in two different objects.

The developers very much prefer this:

Response resp = callReportsService();
Report report = readPayload(resp); // report already contains the attachment as a pdf field

The difference seems little at first glance, but it grows fast when you need to receive 2 or more attachments.

Imagine a snapshot of a chat where each message has its own avatar picture. In SWA, each avatar is sent as an attachment. The code then would have to retrieve every attachment and find the proper place in the data structure to save that avatar. This is a mindless and an error-prone work, which SWA forces us to do.

Hence comes MTOM/XOP.

MTOM/XOP

MTOM relies on application frameworks to extract the attachments from the SOAP messages and place them into the data objects. To do that it needs two things:

1 The XML element which contains (actually, refers) to an attachment should have XSD type of base64Binary.
2 The reference value in that element matches one of the attachments’ Content-ID headers.

Having these two conditions satisfied, the framework’s code can find the attachment by Content-ID, convert it into bytes array and assign to the data object as the value of the referencing element.

In the example below, the data element must be defined as xsd:base64Binary in the service WSDL. The xop:Include element in the response tells the receiving code that the actual value of the data element should be read from an attachment with the Content-ID of ATT1:

HTTP/1.1 200 OK
Date: Thu, 31 May 2018 03:29:38 GMT
Content-Type: multipart/related; type="application/xop+xml"; boundary="1cfbcfcf5bd24ac4ac8c84e2d431bac7"; start="daf16aee1529464db80c1874f81d01b3"; start-info="text/xml"

--1cfbcfcf5bd24ac4ac8c84e2d431bac7
Content-Type: application/xop+xml; charset=UTF-8; type=text/xml
Content-ID: daf16aee1529464db80c1874f81d01b3

    ... SOAP response payload is here ...
    <data>
        <xop:Include href="cid:ATT1" xmlns:xop="http://www.w3.org/2004/08/xop/include"/>
    </data>
    ...

--1cfbcfcf5bd24ac4ac8c84e2d431bac7
Content-Type: application/pdf
Content-ID: <ATT1>
Content-Disposition: attachment; name="contract.pdf"; filename="contract.pdf"
Content-Transfer-Encoding: binary

%PDF-1.7
1308 0 obj
<</Linearized 1/L 643967/O 1314/E 57853/N 5/T 643378/H [ 753 544]>>
endobj
...
--1cfbcfcf5bd24ac4ac8c84e2d431bac7--

MTOM/XOP in MockMotor

To configure a response with XOP attachments:

1 Upload the attachment(s) to the environment.
2 Add the attachment name(s) to the Attachments section of a response.
3 In the same section, set the attachment style to MTOM/XOP.

Instead of attachment names, you can use a script to choose an attachment based on account id or other conditions.

For example, here the first attachment’s name and Content-ID are taken from the mock account properties, and the second one is conditional on the request element <tos/>.

(
    <attachment>
      <name>{$account/*:contractName}</name>
      <content-id>{concat('CID',$account/*:id)}</content-id>
    </attachment>,
    if( $input//*:tos ) then 
      <attachment>
      <name>Standard TOS.pdf</name>
      </attachment>
    else ()
)

Read more about configuring the attachments in the Response Attachments documentation.

Not for REST/JSON

MTOM/XOP is for SOAP only, because it depends on the distinctive element in the XOP namespace to recognize the places where the attachment binary data should be inserted when parsing the payload. JSON attachments cannot have this element (or at least it is not defined for them).

Test Project

I have created a test XOP mock service for this post. The service is included with MockMotor downloadable package and also can be accessed at the Demo Site. You can download the corresponding WSDL and the SoapUI project below.

Download WSDL and SoapUI Project  

Please Share

Was this post useful? Then please share! Tweet This