Azure API 管理 SOAP 到 REST
Azure API Management SOAP to REST
我们正在从旧的 SOAP Web 服务调用转移到新的 Azure Functions/REST API 调用。
我们希望能够使用 Azure API Management 将旧的 SOAP 消息转换为我们客户的 REST 调用,这样他们就不必重写他们的端并可以继续使用 SOAP 消息.
我几乎没有发现任何关于如何进行这项工作的文档。我试过使用我们的旧 SOAP 服务中的 WSDL 来摆弄它,然后将其指向 Azure API 但除了错误我什么也没得到。
我找不到获取任何详细信息的方法。
我知道我需要使用 Liquid 模板将具有大约 10 个属性并且是数据数组的 SOAP 消息转换为 JSON,但我的运气为零。
有人有关于如何让它工作的任何资源吗?
添加以下示例数据。
这就是我们所说的旧版 SOAP 消息。
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ad="http://ad-c.com/">
<soapenv:Header/>
<soapenv:Body>
<ad:ImportItemMovement>
<ad:authenticationToken>0badec32-81f7-4f88-813f-2dbfb62b4484</ad:authenticationToken>
<ad:movementArray>
<ad:WSItemMovementInfo>
<ad:OrgUnitNum>52</ad:OrgUnitNum>
<ad:MovementDateTime>2020-10-06T09:55:50</ad:MovementDateTime>
<ad:RetailSold>5.99</ad:RetailSold>
<ad:QtySold>300</ad:QtySold>
<ad:ItemNum>123456789</ad:ItemNum>
<ad:UpcNum>00021234500000</ad:UpcNum>
</ad:WSItemMovementInfo>
<ad:WSItemMovementInfo>
<ad:OrgUnitNum>54</ad:OrgUnitNum>
<ad:MovementDateTime>2020-10-06T09:55:50</ad:MovementDateTime>
<ad:RetailSold>5.99</ad:RetailSold>
<ad:QtySold>300</ad:QtySold>
<ad:ItemNum>123456789</ad:ItemNum>
<ad:UpcNum>00021234500000</ad:UpcNum>
</ad:WSItemMovementInfo>
</ad:movementArray>
</ad:ImportItemMovement>
</soapenv:Body>
</soapenv:Envelope>
这是在@DSpirit
的帮助下制定的当前政策
<policies>
<inbound>
<base />
<find-and-replace from="ad:" to="" />
<find-and-replace from="soapenv:" to="" />
<xml-to-json kind="direct" apply="always" consider-accept-header="true" />
<trace source="inbound">@(context.Request.Body.As<string>(true))</trace>
<set-body>@{
var body = JObject.Parse(context.Request.Body.As<string>());
return body["Envelope"]["Body"]["ImportItemMovement"]["movementArray"]["WSItemMovementInfo"]?.ToString();
}</set-body>
<set-body template="liquid">
[
{% JSONArrayFor item in body %}
{
"StoreNumber": {{ item.OrgUnitNum }},
"BarcodeNumber": "{{ item.UpcNum }}",
{% if item.WgtSold %}
"Type": "W",
"QuantitySold": {{ item.WgtSold }},
{% endif %}
{% if item.QtySold %}
"Type": "Q",
"QuantitySold": {{ item.QtySold }},
{% endif %}
"TotalRetail": {{ item.RetailSold }},
{% if item.onPromotion %}
"PromotionType": {{ item.onPromotion }},
{% else %}
"PromotionType": 0,
{% endif %}
"SerialNumber": "{{ item.labelSerialNum }}",
"MovementDateTime": "{{ item.MovementDateTime }}"
}
{% endJSONArrayFor %}
]
</set-body>
<!-- Here you should forward the request to the function backend instead of returning it -->
<set-backend-service base-url="https://proxy.freshiq.com/prod/inventory/" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
这是 Azure REST API 所期待的。
[{
"StoreNumber": 0,
"BarcodeNumber": "string",
"Type": "string",
"QuantitySold": 0.5229864343061676,
"TotalRetail": 0.2568850594082819,
"PromotionType": 0,
"SerialNumber": "string",
"MovementDateTime": "string"
},
{
"StoreNumber": 0,
"BarcodeNumber": "string",
"Type": "string",
"QuantitySold": 0.5229864343061676,
"TotalRetail": 0.2568850594082819,
"PromotionType": 0,
"SerialNumber": "string",
"MovementDateTime": "string"
}]
从 SOAP XML 到 REST JSON 的映射是:
OrgUnitNum = StoreNumber
UpcNum = BarcodeNumber
If WgtSold exits Then Type = "W"
If QtySold exist then Type = "Q"
WgtSold if exists or QtySold if exists = QuantitySold
RetailSold = TotalRetail
onPromotion = PromotionType
labelSerialNum = SerialNumber
MovementDateTime = MovementDateTime
上面的内容似乎确实适用于 1 个例外,第 2 个记录的第一个记录生成的 JSON 的 SOAP 字段名称不是 JSON,而是第二个记录在“FOR”循环中是正确的。我不确定是什么原因造成的。
我已经编写了一个策略,returns 我猜是想要的输出。
<policies>
<inbound>
<base />
<find-and-replace from="ad:" to="" />
<find-and-replace from="soapenv:" to="" />
<xml-to-json kind="direct" apply="always" consider-accept-header="true" />
<trace source="inbound">@(context.Request.Body.As<string>(true))</trace>
<set-body>@{
var body = JObject.Parse(context.Request.Body.As<string>());
return body["Envelope"]["Body"]["ImportItemMovement"]["movementArray"]["WSItemMovementInfo"]?.ToString();
}</set-body>
<set-body template="liquid">
{
"StoreNumber": {{ body.OrgUnitNum }},
"BarcodeNumber": "{{ body.UpcNum }}",
{% if body.WgtSold %}
"Type": "W",
"QuantitySold": {{ body.WgtSold }},
{% endif %}
{% if body.QtySold %}
"Type": "Q",
"QuantitySold": {{ body.QtySold }},
{% endif %}
"TotalRetail": {{ body.RetailSold }},
"PromotionType": {{ body.onPromotion }},
"SerialNumber": "{{ body.labelSerialNum }}",
"MovementDateTime": "{{ body.MovementDateTime }}"
}</set-body>
<!-- Here you should forward the request to the function backend instead of returning it -->
<return-response>
<set-status code="200" reason="Ok" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body template="none">@(context.Request.Body.As<string>())</set-body>
</return-response>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
对于此输入:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ad="http://company.com/">
<soapenv:Header/>
<soapenv:Body>
<ad:ImportItemMovement>
<ad:authenticationToken>0badec32-81f7-4f88-813f-8hgty27b4484</ad:authenticationToken>
<ad:movementArray>
<!--Zero or more repetitions:-->
<ad:WSItemMovementInfo>
<ad:OrgUnitNum>52</ad:OrgUnitNum>
<ad:MovementDateTime>2020-10-01T09:55:50</ad:MovementDateTime>
<ad:RetailSold>5.99</ad:RetailSold>
<ad:WgtSold>6</ad:WgtSold>
<ad:ItemNum>123456789</ad:ItemNum>
<ad:UpcNum>00021234500000</ad:UpcNum>
<ad:onPromotion>0</ad:onPromotion>
<ad:labelSerialNum>0123456</ad:labelSerialNum>
</ad:WSItemMovementInfo>
</ad:movementArray>
</ad:ImportItemMovement>
</soapenv:Body>
</soapenv:Envelope>
此政策returns:
{
"StoreNumber": 52,
"BarcodeNumber": "00021234500000",
"Type": "W",
"QuantitySold": 6,
"TotalRetail": 5.99,
"PromotionType": 0,
"SerialNumber": "0123456",
"MovementDateTime": "10/1/2020 9:55:50 AM"
}
我们正在从旧的 SOAP Web 服务调用转移到新的 Azure Functions/REST API 调用。
我们希望能够使用 Azure API Management 将旧的 SOAP 消息转换为我们客户的 REST 调用,这样他们就不必重写他们的端并可以继续使用 SOAP 消息.
我几乎没有发现任何关于如何进行这项工作的文档。我试过使用我们的旧 SOAP 服务中的 WSDL 来摆弄它,然后将其指向 Azure API 但除了错误我什么也没得到。
我找不到获取任何详细信息的方法。
我知道我需要使用 Liquid 模板将具有大约 10 个属性并且是数据数组的 SOAP 消息转换为 JSON,但我的运气为零。
有人有关于如何让它工作的任何资源吗?
添加以下示例数据。
这就是我们所说的旧版 SOAP 消息。
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ad="http://ad-c.com/">
<soapenv:Header/>
<soapenv:Body>
<ad:ImportItemMovement>
<ad:authenticationToken>0badec32-81f7-4f88-813f-2dbfb62b4484</ad:authenticationToken>
<ad:movementArray>
<ad:WSItemMovementInfo>
<ad:OrgUnitNum>52</ad:OrgUnitNum>
<ad:MovementDateTime>2020-10-06T09:55:50</ad:MovementDateTime>
<ad:RetailSold>5.99</ad:RetailSold>
<ad:QtySold>300</ad:QtySold>
<ad:ItemNum>123456789</ad:ItemNum>
<ad:UpcNum>00021234500000</ad:UpcNum>
</ad:WSItemMovementInfo>
<ad:WSItemMovementInfo>
<ad:OrgUnitNum>54</ad:OrgUnitNum>
<ad:MovementDateTime>2020-10-06T09:55:50</ad:MovementDateTime>
<ad:RetailSold>5.99</ad:RetailSold>
<ad:QtySold>300</ad:QtySold>
<ad:ItemNum>123456789</ad:ItemNum>
<ad:UpcNum>00021234500000</ad:UpcNum>
</ad:WSItemMovementInfo>
</ad:movementArray>
</ad:ImportItemMovement>
</soapenv:Body>
</soapenv:Envelope>
这是在@DSpirit
的帮助下制定的当前政策 <policies>
<inbound>
<base />
<find-and-replace from="ad:" to="" />
<find-and-replace from="soapenv:" to="" />
<xml-to-json kind="direct" apply="always" consider-accept-header="true" />
<trace source="inbound">@(context.Request.Body.As<string>(true))</trace>
<set-body>@{
var body = JObject.Parse(context.Request.Body.As<string>());
return body["Envelope"]["Body"]["ImportItemMovement"]["movementArray"]["WSItemMovementInfo"]?.ToString();
}</set-body>
<set-body template="liquid">
[
{% JSONArrayFor item in body %}
{
"StoreNumber": {{ item.OrgUnitNum }},
"BarcodeNumber": "{{ item.UpcNum }}",
{% if item.WgtSold %}
"Type": "W",
"QuantitySold": {{ item.WgtSold }},
{% endif %}
{% if item.QtySold %}
"Type": "Q",
"QuantitySold": {{ item.QtySold }},
{% endif %}
"TotalRetail": {{ item.RetailSold }},
{% if item.onPromotion %}
"PromotionType": {{ item.onPromotion }},
{% else %}
"PromotionType": 0,
{% endif %}
"SerialNumber": "{{ item.labelSerialNum }}",
"MovementDateTime": "{{ item.MovementDateTime }}"
}
{% endJSONArrayFor %}
]
</set-body>
<!-- Here you should forward the request to the function backend instead of returning it -->
<set-backend-service base-url="https://proxy.freshiq.com/prod/inventory/" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
这是 Azure REST API 所期待的。
[{
"StoreNumber": 0,
"BarcodeNumber": "string",
"Type": "string",
"QuantitySold": 0.5229864343061676,
"TotalRetail": 0.2568850594082819,
"PromotionType": 0,
"SerialNumber": "string",
"MovementDateTime": "string"
},
{
"StoreNumber": 0,
"BarcodeNumber": "string",
"Type": "string",
"QuantitySold": 0.5229864343061676,
"TotalRetail": 0.2568850594082819,
"PromotionType": 0,
"SerialNumber": "string",
"MovementDateTime": "string"
}]
从 SOAP XML 到 REST JSON 的映射是:
OrgUnitNum = StoreNumber
UpcNum = BarcodeNumber
If WgtSold exits Then Type = "W"
If QtySold exist then Type = "Q"
WgtSold if exists or QtySold if exists = QuantitySold
RetailSold = TotalRetail
onPromotion = PromotionType
labelSerialNum = SerialNumber
MovementDateTime = MovementDateTime
上面的内容似乎确实适用于 1 个例外,第 2 个记录的第一个记录生成的 JSON 的 SOAP 字段名称不是 JSON,而是第二个记录在“FOR”循环中是正确的。我不确定是什么原因造成的。
我已经编写了一个策略,returns 我猜是想要的输出。
<policies>
<inbound>
<base />
<find-and-replace from="ad:" to="" />
<find-and-replace from="soapenv:" to="" />
<xml-to-json kind="direct" apply="always" consider-accept-header="true" />
<trace source="inbound">@(context.Request.Body.As<string>(true))</trace>
<set-body>@{
var body = JObject.Parse(context.Request.Body.As<string>());
return body["Envelope"]["Body"]["ImportItemMovement"]["movementArray"]["WSItemMovementInfo"]?.ToString();
}</set-body>
<set-body template="liquid">
{
"StoreNumber": {{ body.OrgUnitNum }},
"BarcodeNumber": "{{ body.UpcNum }}",
{% if body.WgtSold %}
"Type": "W",
"QuantitySold": {{ body.WgtSold }},
{% endif %}
{% if body.QtySold %}
"Type": "Q",
"QuantitySold": {{ body.QtySold }},
{% endif %}
"TotalRetail": {{ body.RetailSold }},
"PromotionType": {{ body.onPromotion }},
"SerialNumber": "{{ body.labelSerialNum }}",
"MovementDateTime": "{{ body.MovementDateTime }}"
}</set-body>
<!-- Here you should forward the request to the function backend instead of returning it -->
<return-response>
<set-status code="200" reason="Ok" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body template="none">@(context.Request.Body.As<string>())</set-body>
</return-response>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
对于此输入:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ad="http://company.com/">
<soapenv:Header/>
<soapenv:Body>
<ad:ImportItemMovement>
<ad:authenticationToken>0badec32-81f7-4f88-813f-8hgty27b4484</ad:authenticationToken>
<ad:movementArray>
<!--Zero or more repetitions:-->
<ad:WSItemMovementInfo>
<ad:OrgUnitNum>52</ad:OrgUnitNum>
<ad:MovementDateTime>2020-10-01T09:55:50</ad:MovementDateTime>
<ad:RetailSold>5.99</ad:RetailSold>
<ad:WgtSold>6</ad:WgtSold>
<ad:ItemNum>123456789</ad:ItemNum>
<ad:UpcNum>00021234500000</ad:UpcNum>
<ad:onPromotion>0</ad:onPromotion>
<ad:labelSerialNum>0123456</ad:labelSerialNum>
</ad:WSItemMovementInfo>
</ad:movementArray>
</ad:ImportItemMovement>
</soapenv:Body>
</soapenv:Envelope>
此政策returns:
{
"StoreNumber": 52,
"BarcodeNumber": "00021234500000",
"Type": "W",
"QuantitySold": 6,
"TotalRetail": 5.99,
"PromotionType": 0,
"SerialNumber": "0123456",
"MovementDateTime": "10/1/2020 9:55:50 AM"
}