Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

SOAP

A SOAP service with three operations, for XML routing, SOAP-to-REST and WSDL demos.

RoutePurpose
POST /soapThe SOAP endpoint (1.1 and 1.2)
GET /soap?wsdl, GET /soap/wsdlWSDL 1.1 with SOAP 1.1 and SOAP 1.2 bindings
OperationNamespace of the request elementInputOutput
GetUserhttp://rustybin.local/usersuserIduser with id, name, email, role
CreateOrderhttp://rustybin.local/ordersmerchantId, amount, currencyorderId, the input, status ACCEPTED, timestamp
GetStatushttp://rustybin.local/statusorderIdstatus, createdAt, updatedAt, tracking

Version: taken from the envelope namespace (authoritative), else from the Content-Type (text/xml is 1.1, application/soap+xml is 1.2). The response uses the same version and content type. An unknown envelope namespace is a VersionMismatch fault.

Dispatch: by SOAPAction (1.1) or the action parameter of the Content-Type (1.2), falling back to the first element of the Body when the action is empty or unknown.

Faults: SOAP 1.1 faults (faultcode, faultstring, detail) use HTTP 500; SOAP 1.2 faults (Code, Reason, Detail) use 400 for env:Sender and 500 otherwise, as the SOAP 1.2 HTTP binding specifies. Every value taken from the request is XML-escaped.

POST {{base_url}}/soap
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://rustybin.local/GetUser"

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> soap:Body 123 </soap:Body> </soap:Envelope>

HTTP 200
[Asserts]
header "Content-Type" == "text/xml; charset=utf-8"
xpath "string(//*[local-name()='GetUserResponse']/*[local-name()='user']/*[local-name()='id'])" == "123"
POST {{base_url}}/soap
Content-Type: application/soap+xml; charset=utf-8; action="http://rustybin.local/CreateOrder"

<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"> env:Body M00142.50EUR </env:Body> </env:Envelope>

HTTP 200
[Asserts]
header "Content-Type" == "application/soap+xml; charset=utf-8"
xpath "string(//*[local-name()='CreateOrderResponse']/*[local-name()='status'])" == "ACCEPTED"
xpath "string(//*[local-name()='CreateOrderResponse']/*[local-name()='amount'])" == "42.50"
POST {{base_url}}/soap
Content-Type: text/xml

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> soap:Body</soap:Body> </soap:Envelope>

HTTP 500
[Asserts]
xpath "string(//faultcode)" == "soap:Client"
xpath "string(//faultstring)" == "Unknown operation"
POST {{base_url}}/soap
Content-Type: application/soap+xml

<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"> env:Body</env:Body> </env:Envelope>

HTTP 400
[Asserts]
xpath "string(//*[local-name()='Code']/*[local-name()='Value'])" == "env:Sender"

The WSDL's soap:address is derived from the request (X-Forwarded-* honoured with RUSTYBIN_TRUST_FORWARD=true), so a WSDL fetched through a gateway points back at the gateway:

GET {{base_url}}/soap?wsdl
HTTP 200
[Asserts]
header "Content-Type" contains "xml"
xpath "count(//*[local-name()='operation' and @name='GetStatus'])" >= 1
body contains "{{base_url}}/soap"