【问题标题】:Need to modify response using Azure APIM set-body policy需要使用 Azure APIM set-body 策略修改响应
【发布时间】:2020-11-16 10:07:30
【问题描述】:

我对 Azure APIM 比较陌生,我有这个后端,我可以调用它以格式返回响应

{
    "data": {
        "attributes": {
            "municipalities": []
        }
    }
}

我想修改响应,以便以格式返回数据

{
    "data": {
            "municipalities": []
    }
}

我尝试过使用设置的体液模板

<outbound>
<set-body template="liquid">
   {
        "data": {
                "municipalities": {{body.data.attributes.municipalities}}
               }
    }</set-body>
</outbound>

但我得到的回应只是

{
    "data": {
        "municipalities":
    }
}

如果有人可以向我指出我做错了什么或者是否有更好的方法来做到这一点?

我还尝试使用以下代码来检查我是否能够检索“数据”属性,但在 Azure APIM 测试的跟踪部分中出现以下错误

<outbound>
    <set-body> 
    @{ 
        JObject inBody = context.Request.Body.As<JObject>();
        return inBody["data"].ToString(); 
    } 
    </set-body>
</outbound>

错误:

{
    "messages": [
        {
            "message": "Expression evaluation failed.",
            "expression": " \n    JObject inBody = context.Request.Body.As<JObject>();\n    return inBody[\"data\"].ToString(); \n",
            "details": "Object reference not set to an instance of an object."
        },
        "Expression evaluation failed. Object reference not set to an instance of an object.",
        "Object reference not set to an instance of an object."
    ]
}

【问题讨论】:

  • 嗨,乐高,请参阅下面提供的解决方案。如果它对您的问题有帮助,请accept它作为答案(单击我的答案旁边的复选标记,将其从灰色切换为已填充)。先谢谢了~
  • @HuryShen 感谢您的回复,但是如果我的 API 上有 3 条不同的路由,例如 GET /muncipalities、GET /names GET/schools 并且每个路由都有自己的返回模式,这将很棘手例如 body.data.attributes.municipalities 、 body.data.attributes.names 、 body.data.attributes.schools ,每个都有不同的返回值。有没有一种更简单的方法可以从所有中删除 .attributes 部分,而不必分别编写每个数组项的每个属性?因为这将需要为我的 3 条路线制定 3 条单独的政策???
  • Hi LeGo 在谈论“有没有更简单的方法...”之前,我认为您需要检查是否可以在&lt;outbound&gt;&lt;set-body&gt; 下获取响应数据。根据一些测试,我猜你在那里没有得到响应数据成功。
  • 请参考我回答中的“更新”。
  • 抱歉很忙,所以现在只能尝试,但它是完美的:)

标签: azure azure-api-management


【解决方案1】:

由于body.data.attributes.municipalities是一个数组,我们不能直接把"municipalities":放进去。为了您修改json数据格式的要求,我们需要编写每个数组项的每个属性。以下是我的步骤供您参考。

我的json是:

{
    "data": {
        "attributes": {
            "municipalities": [
                {
                    "name": "hury",
                    "email": "hury@mail.com"
                },
                {
                    "name": "mike",
                    "email": "mike@email.com"
                }
            ]
        }
    }
}

我的液体模板显示为:

===============================更新========= ====================

首先您分享的代码JObject inBody = context.Request.Body.As&lt;JObject&gt;(); 无法获取响应数据。你应该使用JObject inBody = context.Response.Body.As&lt;JObject&gt;();

那么对于您关于“是否有更简单的方法来删除.attributes 部分的问题,我在下面提供了一个解决方案供您参考。

不要使用液体模板,使用Replace"attributes": { 替换为空,并使用Substring 删除最后一个}

<set-body>@{ 
    JObject inBody = context.Response.Body.As<JObject>();
    string str = inBody.ToString();
    string str1 = str.Replace("\"attributes\": {", "");
    string result = str1.Substring(0, str1.Length-1);
    return result; 
}</set-body>

注意:这种方法需要对您的响应数据格式进行高度规范。

【讨论】:

  • 这很棒,也很有效。完全是我想要的。谢谢:)
  • 嗨@LeGo 能否请您将我的回答标记为“已接受”,谢谢~
【解决方案2】:

我还设法用下面的代码得到了想要的输出,这样代码是通用的,不需要做任何字符串操作。

<set-body>@{ 
    JToken inBody = context.Response.Body.As<JToken>()["data"]["attributes"];
    JObject jsonObject = new JObject{
    ["data"] = inBody
}; 
return jsonObject.ToString();
}</set-body>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-01
    • 2017-08-28
    • 2022-08-16
    • 1970-01-01
    • 1970-01-01
    • 2020-10-29
    • 1970-01-01
    相关资源
    最近更新 更多