Open hilsonp opened 1 year ago
Hi @hilsonp, thank you for describing this.
One thing to try is to set the operator
in the XPath matcher, for example:
resources:
- method: POST
path: "/something"
requestBody:
xPath: "/env:Envelope/env:Body/op:operationOne"
operator: Exists
response:
statusCode: 202
content: "Yahoo we got it"
More details added here: https://docs.imposter.sh/request_matching/#body-match-operators
Edit: fixed name of property - thanks!
Hello @outofcoffee
Thank you. It works ! Note: in your last comment, you made a typo: It is operator and not operation ;-)
Here is what we will use imposter to expose SOAP mocks without needing to store the contract (unless you make a 'light' mode for the 'soap' plugin ;-) )
plugin: rest
basePath: /imposter/test/v1 # Put here what the basePath found in the provider contrat as: soap:address location
system:
xmlNamespaces:
soap: "http://schemas.xmlsoap.org/soap/envelope/"
operation: "http://example.com/services/imposterTest/messages/v1"
resources:
- method: POST
requestBody:
xPath: "/soap:Envelope/soap:Body/operation:operationOne"
operator: Exists
response:
statusCode: 202
content: "Yahoo we got it"
I'm sure you got my point but just in case, the same mock may be declared in a soap "light" mode (by specifying a wsdlNamespaces instead of wsdlFile) with this minimalist and clean config:
plugin: soap
basePath: /imposter/test/v1
wsdlNamespaces:
soap: "http://schemas.xmlsoap.org/soap/envelope/"
operation: "http://example.com/services/imposterTest/messages/v1"
resources:
- operation: operationOne
response:
statusCode: 202
content: "Yahoo we got it"
Hello,
I olmost nailed it and we finish our implementation for SOAP mocks.
I really like the way imposter can generate a mock from openapi or wsdl contracts. This is absolutely clever !
Nevertheless, our use case is that we mock apis and web services of providers. The contract quality is too different from one provider to another hence we never base our mocks on the provider contract. Instead we exclusively make imposter respond based on files (json/xml) that we maintain, groovy, templates or a mix of everything ;-) The most important being that we do NOT use their contract other than for documentation purposes.
This being said:
REST
For REST mocks, it is easy, we use the rest plugin (and not the OpenAPI plugin) and fully qualify the resources matching as well as the responses in the imposter-config.yaml.
SOAP
For SOAP thought, the soap plugin requires the contract which forces us to copy/maintain a version of the provider contract. This is something I wanted to avoid. Then, I though I would mock a SOAP as any HTTP service, matching the operation with an xpath. Instead of giving the contract, I only need to declare system.xmlNamespaces
Here is an example of soap message I need to match:
The way I send it is:
curl -v --request POST --header "Content-Type: text/xml;charset=UTF-8" --data '<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:op="http://example.com/services/imposterTest/messages/v1"><env:Header/><env:Body> <op:operationOne><truc>much</truc></op:operationOne></env:Body></env:Envelope>' http://localhost:8080/
Here is an imposter-config.yaml that matches it (although it does not let me achieve my goal yet).
The log is the following and I received the 202 with "Yahoo we got it":
I do not want to match /env:Envelope/env:Body/op:operationOne/truc but only check that /env:Envelope/env:Body/op:operationOne exists.
Then I tried:
But the reply is a 200 (maybe same as https://github.com/outofcoffee/imposter/issues/395) with no content:
and the log shows:
I also tried just giving the xPath and not giving a value (as I only want to check that the operationOne element exists):
The same 200 with empty response happen.
Ultimately
The first (minimalist) thing I tried was this I removed the basePath because it seemed to introduce some strange behaviour) This also failed because it would only allow GET (and not POST)
The dream
Since, as far as I know, the SOAP operation is always the first element under the /envelope/body, I would love being able to:
Like this:
Hoping you can find a working equivalent to "string(boolean(/env:Envelope/env:Body/op:operationOne))". Hoping you the soaplight is inspiring ;-)
Best regards.