Note: I am completely not a WSDL/SOAP expert here – do if some expert reads this and tells me that I missed the point completely – I would very much appreciate it. Thanks in advance.
I started playing with trying to send some Full LTI SOAP messages back and forth between a PHP server and a PHP client. I got pretty close pretty quickly but got stuck on the same thing that got me stuck back in 2007 when I tried to build a PHP harness for TI 1.0 – the problem is in WSDL that looks like this:
<wsdl:message name="registerToolRequest"> <wsdl:part name="Parameters" element="tns:registerToolRequest"/> <wsdl:part name="HeaderInfoParameters" element="tns:imsx_syncRequestHeaderInfo"/> </wsdl:message>
<wsdl:input> <soap11:body use="literal" parts="Parameters"/> <soap11:header message="tns:registerToolRequest" part="HeaderInfoParameters" use="literal" wsdl:required="true"/> </wsdl:input>
If you look on the web, it is very rare when you see a wsdl:message with more than one wsdl:part within it – as a matter of fact, other than IMS WSDL, I could find no other examples of multiple uses of wsdl:part within a wsdl:message.
I hoped that it was simply prohibited :). I looked at the WDSL spec at:
And was disappointed to see:
<element ref="wsdl:part" minOccurs="0" maxOccurs="unbounded"/>
And it clearly allows many parts, schema-wise. The search continues.
Then I started looking at the WS-I Basic Profile aimed at scoping WSDL/SOAP down in the name of interoperability:
And while it did not flatly prohibit multiple parts in a message it did have a few recommendations around parts, messages, and literal encoding, in particular:
R2210 If a document-literal binding in a DESCRIPTION does not specify the parts attribute on a soapbind:body element, the corresponding abstract wsdl:message MUST define zero or one wsdl:parts.
R2301 The order of the elements in the soap:body of a MESSAGE MUST be the same as that of the wsdl:parts in the wsdl:message that describes it.
Neither seemed to prohibit multiple wsdl:part items – but it made me a little nervous – where there is smoke, there might be fire.
In all my testing of PHP, it really wanted to send the two parameters as two parameters and then the server would freak out as its view of the WSDL was that there was one parameter – as a matter of fact, if you asked PHP the proper signature for the RegisterTool – it showed this:
registerToolResponse registerTool(registerToolRequest $Parameters)
So then I went looking for how PHP folks make WSDL and happened across this tool:
I never ran this tool, but while examining the file SoapService.php, it seemed like it did allow for situations where there were multiple wsdl:part entries for a wsdl:message – but looking closer, it did *not* use “literal” in its soap:body.
Given that the best practice document seemed so nervous about “literal”, I decided to give encoded a try. So I changed the WSDL to be:
<wsdl:input> <soap11:body use="encoded" namespace="urn:xmethods-delayed-quotes" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </wsdl:input>
And poof! Everything worked. My client calls passed in two parameters and two parameters happily arrived in my server with all the right shapes and sizes. Now my PHP SoapClient thinks this is the registerTool signature:
registerToolResponse registerTool(registerToolRequest $Parameters, imsx_RequestHeaderInfo.Type $HeaderInfoParameters)
I don’t fully know what this means – but it is a starting point to investigate more.