API Management - Convert SOAP POST to GET
Tags: azure, programming, api, csharp
Published: 2022-06-21 16:52:24

API Management is receiving a SOAP POST request with XML in the request body.
Data from the request body has to be forwarded to a GET operation

## Import SOAP Service

The public soap service 
[https://www.dataaccess.com/webservicesserver/numberconversion.wso?op=NumberToDollars](https://www.dataaccess.com/webservicesserver/numberconversion.wso?op=NumberToDollars) is [imported in API Management](https://docs.microsoft.com/en-us/azure/api-management/import-soap-api).


![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1655368077111/XaYrAzMPk.png?auto=compress,format&format=webp align="left")

The imported SOAP service in API management:
![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1655368137007/RoGHE7cMu.png?auto=compress,format&format=webp align="left")

Request-Body for SOAP service:
```xml
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns="http://www.w3.org/2003/05/soap-envelope">
  <Body>
    <NumberToDollars xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.dataaccess.com/webservicesserver/">
      <dNum>1</dNum>
    </NumberToDollars>
  </Body>
</Envelope>
```


## The target API

An additional operation in the Echo API returns the [mocked](https://docs.microsoft.com/en-us/azure/api-management/api-management-advanced-policies#mock-response) status 200.


![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1655368236887/kZvqjpBme.png?auto=compress,format&format=webp align="left")

```xml
<policies>
    <inbound>
        <base />
        <mock-response status-code="200" content-type="application/json" />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>
```

This target API has to be replaced with a real-world API.

## Transform POST to GET

The incoming request body is escaped and also has additional double quotes which has to be removed:

```csharp
string xml = context.Request.Body.As<string>(preserveContent: true);
xml = Regex.Unescape(xml);

// Remove the double quotes
xml = xml.Remove(0,1);
xml = xml.Remove(xml.Length-1,1);
```
Transform the XML string into a JSON object:

```csharp
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);

var json = JsonConvert.SerializeObject(doc);
var data = JObject.Parse(json );
```
The transformed JSON string:

```json
{
  "?xml": {
    "@version": "1.0",
    "@encoding": "utf-8"
  },
  "Envelope": {
    "@xmlns": "http://www.w3.org/2003/05/soap-envelope",
    "Body": {
      "NumberToDollars": {
        "@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
        "@xmlns": "http://www.dataaccess.com/webservicesserver/",
        "dNum": "1"
      }
    }
  }
}
```
Finally, the wanted data has to be returned from the JSON Object:

```csharp
JObject envelope = data["Envelope"] as JObject;
JObject body = envelope["Body"] as JObject;
JObject numberToDollars = body["NumberToDollars"] as JObject;

return numberToDollars["dNum"].Value<string>();

```
The data has to be forwarded to the mocked API with a [GET](https://docs.microsoft.com/en-us/azure/api-management/api-management-advanced-policies#SetRequestMethod) request:

```xml
<set-method>GET</set-method>
<set-backend-service base-url="https://rfqapiservicey27itmeb4cf7q.azure-api.net/echo/200/" />
<rewrite-uri template="@("/test?q=" + context.Variables.GetValueOrDefault<string>("num"))" copy-unmatched-params="false" />

```
## Result

The complete policy:
```xml
<policies>
    <inbound>
        <base />
        <set-variable name="num" value="@{
            string xml = context.Request.Body.As<string>(preserveContent: true);
            xml = Regex.Unescape(xml);

            // Remove the double quotes
            xml = xml.Remove(0,1);
            xml = xml.Remove(xml.Length-1,1);

            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);

            var data = JObject.Parse(JsonConvert.SerializeObject(doc));
            JObject envelope = data["Envelope"] as JObject;
            JObject body = envelope["Body"] as JObject;
            JObject numberToDollars = body["NumberToDollars"] as JObject;

            return numberToDollars["dNum"].Value<string>();
            }" />
        <set-method>GET</set-method>
        <set-backend-service base-url="https://rfqapiservicey27itmeb4cf7q.azure-api.net/echo/200/" />
        <rewrite-uri template="@("/test?q=" + context.Variables.GetValueOrDefault<string>("num"))" copy-unmatched-params="false" />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>
```

Testing it in API management:


![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1655369014527/IUTrppBM9.png?auto=compress,format&format=webp align="left")

The trace log:

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1655369043812/wLkIn0y9Q.png?auto=compress,format&format=webp align="left")


[GitHub answer](https://stackoverflow.com/questions/49103525/convert-post-to-get-azure-api-management-rest-api/72642348#72642348)