简体   繁体   English

Azure API 管理 SOAP 到 REST

[英]Azure API Management SOAP to REST

We are moving from old SOAP Web Service calls for our customers to call to new Azure Functions/REST API calls.我们正在从客户的旧 SOAP Web 服务调用转向新的 Azure Functions/REST API 调用。

We would like to be able to use Azure API Management to convert the OLD SOAP messages into REST calls for our customers so that they do not have to rewrite their side and can continue to use the SOAP messages.我们希望能够使用 Azure API 管理为我们的客户将 OLD SOAP 消息转换为 REST 调用,这样他们就不必重写自己的一面并可以继续使用 SOAP 消息。

I've found little to no documentation on how to make this work.我发现几乎没有关于如何进行这项工作的文档。 I've tried fiddling with it using the WSDL from our Old SOAP services and then pointing that to the Azure API but I get nothing but errors.我尝试使用旧 SOAP 服务中的 WSDL 摆弄它,然后将其指向 Azure API,但除了错误之外我什么也没得到。

I don't see a way to get any detailed info.我看不到获取任何详细信息的方法。

I understand that I need to use the Liquid Templates to transform the SOAP Message which has about 10 properties and is an array of data into JSON but I've had zero luck figuring that out.我知道我需要使用 Liquid 模板来将具有大约 10 个属性并且是一组数据的 SOAP 消息转换为 JSON,但我的运气为零。

Does anyone have any resources on how to get this to work?有没有人有关于如何让它工作的任何资源?

Adding the below example data.添加以下示例数据。

This is what we call the Legacy SOAP Message.这就是我们所说的 Legacy SOAP Message。

<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>

Here is the CURRENT policy with the help of @DSpirit这是在@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>

Here is what the Azure REST API is expecting.这是 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"
  }]

The mapping from SOAP XML to REST JSON is:从 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

With the above it does seem to work with 1 exception the JSON that is produced the first record of the 2 has the names of the SOAP fields not the JSON ones but the second record in the "FOR" loop is correct.使用上面的内容,它似乎可以正常工作,但有 1 个例外,生成 2 个的第一条记录的 JSON 具有 SOAP 字段的名称,而不是 JSON 字段的名称,但“FOR”循环中的第二条记录是正确的。 I'm not sure what would cause that.我不确定是什么原因造成的。

I've scrapcoded a policy which returns the desired output I guess.我已经废弃了一个策略,它返回我猜想要的输出。

<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>

For this input:对于此输入:

<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>

This policy returns:此政策返回:

{
    "StoreNumber": 52,
    "BarcodeNumber": "00021234500000",

    "Type": "W",
    "QuantitySold": 6,


    "TotalRetail": 5.99,
    "PromotionType": 0,
    "SerialNumber": "0123456",
    "MovementDateTime": "10/1/2020 9:55:50 AM"
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM