soap to rest to soap using apigee.

Hi everyone,

I am trying to make a proxy for soap-to-rest-to-soap. I want to pass the entire request xml as a attribute in json to my target endpoint. My json body should look like as given

{

"body":"<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelopexmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Header>..."

}

It is a sample request I have taken from web.

Kindly guide me for this. Solution provide soon would be appreciated.

Thanks in advance,

Sumit Yadav

Solved Solved
0 7 859
1 ACCEPTED SOLUTION

ok, I think I understand what you're describing.

In an Apigee proxy, the payload of a request is available via a context variable called "request.content".

The full XML of an inbound soap request is available there. You can't just embed it directly in the right-hand-side of a JSON property, because that XML might have double quotes, and in JSON the double-quotes have to be escaped. Fortunately in the "message template" of Apigee, there is a function you can use, escapeJSON, to make that all work correctly.

So what you could do is

<AssignMessage name='AM-Embed'>
  <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
  <Set>
    <Payload contentType='application/json'>{
  "body": "{escapeJSON(request.content)}"
}
</Payload>
  </Set>
</AssignMessage>

This is the result I see

{
  "body": "<soap:Envelope xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"               xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"               xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> <soap:Header>    <wsse:Security>      <wsu:Timestamp wsu:Id=\"Timestamp-7cd6d5e5\">        <wsu:Created>2020-08-04</wsu:Created>      </wsu:Timestamp>    </wsse:Security>  </soap:Header>  <soap:Body>    <Operation>      data here    </Operation>  </soap:Body></soap:Envelope>"
}

Check it out, all of the double-quotes are escaped as we wanted.

The converse, extracting the right-hand-side of a JSON property into ... the request content, which you must do on the response side, is a little different because you must un-embed a string from the full content.

The full content of the response comes back and you want to get just one piece of it, a subset of it.

To do that you need to use jsonpath to reach into the JSON. Fortunately, again, there is a function for that in the message template. This is what it looks like:

<AssignMessage name='AM-UnEmbed'>
  <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
  <AssignVariable>
    <Name>jpath1</Name>
    <Value>$.body</Value>
  </AssignVariable>
  <Set>
    <Payload contentType='application/xml'>{jsonPath(jpath1,response.content)}</Payload>
  </Set>
</AssignMessage>

Doing it that way gets you the XML. There's no need to "unescape" the quotes - that happens automatically.

View solution in original post

7 REPLIES 7

Can you clarify what you're REALLY trying to do?

The client is sending in SOAP.

You want the Apigee proxy to ... transform the SOAP (XML) into JSON, and then... ?? embed that JSON as a single attribute in a JSON document? In other words JSON in JSON ?

Maybe provide some more details about the desired shape of the JSON payload? (provide more than just the "body" )

Hi Dino,

Thanks for replying.

So making it more clear I would say the client is invoking soap end point with its request xml, I want to provide a proxy with apigee that transforms soap(xml) into json, which I have to send as payload to the target endpoint which is a aws api gateway. The payload should have entire request xml embeded in json its structure should be like

{

"body":"<?xml version ="1.0"?><SOAP-ENV:Envelope

   xmlns:SOAP-ENV ="http://www.w3.org/2001/12/soap-envelope" 

SOAP-ENV:encodingStyle ="http://www.w3.org/2001/12/soap-encoding"><SOAP-ENV:Body xmlns:m ="http://www.xyz.org/quotation"><m:GetQuotationResponse><m:Quotation>Hereis the quotation</m:Quotation></m:GetQuotationResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>"

}

Where body is an attribute which have entire request xml.

I have aws lambda in the backend integrated with api gateway which processes this json and sends back the xml response embedded in json like above that I have to convert again at apigee and send response xml to client extracting it from body attribute.

Thanks.

ok, I think I understand what you're describing.

In an Apigee proxy, the payload of a request is available via a context variable called "request.content".

The full XML of an inbound soap request is available there. You can't just embed it directly in the right-hand-side of a JSON property, because that XML might have double quotes, and in JSON the double-quotes have to be escaped. Fortunately in the "message template" of Apigee, there is a function you can use, escapeJSON, to make that all work correctly.

So what you could do is

<AssignMessage name='AM-Embed'>
  <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
  <Set>
    <Payload contentType='application/json'>{
  "body": "{escapeJSON(request.content)}"
}
</Payload>
  </Set>
</AssignMessage>

This is the result I see

{
  "body": "<soap:Envelope xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"               xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"               xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> <soap:Header>    <wsse:Security>      <wsu:Timestamp wsu:Id=\"Timestamp-7cd6d5e5\">        <wsu:Created>2020-08-04</wsu:Created>      </wsu:Timestamp>    </wsse:Security>  </soap:Header>  <soap:Body>    <Operation>      data here    </Operation>  </soap:Body></soap:Envelope>"
}

Check it out, all of the double-quotes are escaped as we wanted.

The converse, extracting the right-hand-side of a JSON property into ... the request content, which you must do on the response side, is a little different because you must un-embed a string from the full content.

The full content of the response comes back and you want to get just one piece of it, a subset of it.

To do that you need to use jsonpath to reach into the JSON. Fortunately, again, there is a function for that in the message template. This is what it looks like:

<AssignMessage name='AM-UnEmbed'>
  <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
  <AssignVariable>
    <Name>jpath1</Name>
    <Value>$.body</Value>
  </AssignVariable>
  <Set>
    <Payload contentType='application/xml'>{jsonPath(jpath1,response.content)}</Payload>
  </Set>
</AssignMessage>

Doing it that way gets you the XML. There's no need to "unescape" the quotes - that happens automatically.

Thank you so much Dino. It is really helpfull to me.

Hi Dino,

Moving ahead I was thrown a new challenge where I am receiving a String JSON from target server and I am unable to figure out how to convert it to the desired result.

The response from the target server is something like this-

"{"result":"success","body":"<soap:Envelope xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"               xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"               xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> <soap:Header>    <wsse:Security>      <wsu:Timestamp wsu:Id=\"Timestamp-7cd6d5e5\">        <wsu:Created>2020-08-04</wsu:Created>      </wsu:Timestamp>    </wsse:Security>  </soap:Header>  <soap:Body>    <Operation>      data here    </Operation>  </soap:Body></soap:Envelope>"}"

My desired response is the value of body if result is success i.e the entire xml as I have soap endpoint consuming this response with the escape characters removed. I know it is something that would go into javascript. How can I achieve this?

Did you see my "AM-UnEmbed" policy?

It should do what you want. Did you try that? what results did you get?

Yes Dino I tried your AM-Unembad earlier. But I actually needed it to parse into json object before throwing to AM-Unmebed. So after parsing I got it resolved with your AM-Unembed and it works fine now.

Thanks for your kind support.