【问题标题】:How to use a variable when returning response in policy definition?在策略定义中返回响应时如何使用变量?
【发布时间】:2020-01-25 16:32:41
【问题描述】:

我正在 Azure API 管理实例中配置入站策略。

首先,我设置一个变量:

<set-variable name="var1" value="" />

然后我发送请求

<send-request mode="new" response-variable-name="var1" timeout="20" ignore-error="false">

返回 JSON。测试时,我在跟踪选项卡中收到以下消息:

已发送对“https://my-api.azure-api.net/api/data”的 GET 请求,结果存储在“var1”变量中。

我猜发送请求策略有效,结果存储在变量中。 然后我想返回一个响应(仍在入站,尝试在出站时得到 500):

<return-response response-variable-name="existing response variable">
    <set-status code="200" reason="OK" />
    <set-header name="Content-Type" exists-action="override">
        <value>application/json</value>
    </set-header>
    <set-body>
    {
        "success": true,
        "var1": context.Variables["var1"]
    }
    </set-body>
</return-response>

我的问题是它不起作用...它只是呈现context.Variables["var1"]。

也是如此:

  • @context.Variables["var1"]
  • @{ context.Variables.GetValueOrDefault&lt;string&gt;("var1") }
  • @context.Variables.GetValueOrDefault("var1")

所有这些都按书面形式呈现,没有提取任何值。

编辑:我也尝试添加占位符字符串,然后使用

<find-and-replace from="Placeholder" to="context.Variables.GetValueOrDefault("var1")" />

并尝试将其放置在入站和出站中。但这项政策并未推出。

这是一个 JSON 对象,我想附加到响应中(小细节:实际上我遇到了多个变量的问题)。

我的问题是:如何将我声明的变量添加到响应中?

【问题讨论】:

    标签: azure string-concatenation azure-api-management


    【解决方案1】:

    有两种方法可以解决这个问题。您可以为此使用策略表达式:https://docs.microsoft.com/en-us/azure/api-management/api-management-policy-expressions。要记住的是,它们只能用于构建策略的整体价值,而不是其中的一部分,所以:

    <set-body>@("{\"success\": true, \"var1\": " + ((IResponse)context.Variables["var1"]).Body.As<string>() + "}"</set-body>
    

    或者使用set-body 策略,您可以使用液体模板:

    <set-variable name="var1body" value="@((IResponse)context.Variables["var1"]).Body.As<string>())" />
    <set-body template="liquid">
    {
        "success": true,
        "var1": {{context.Variables["var1body"]}}
    }
    </set-body>
    

    【讨论】:

    • 首先,你在 set-varialbe 中有一个错字;-)
    • 其次,我有点没有注意到 set-variable 策略具有解析响应的逻辑,但今天尝试了一下,它解决了我的问题。谢谢你,维塔利 :-)
    【解决方案2】:

    我假设您在主请求流程之外还有一些 sidecar 请求。

    此示例将来自send-request 的响应添加到主请求的响应正文中:

    <policies>
        <inbound>
            <base />
            <!-- main request -->
            <set-backend-service base-url="https://reqres.in" />
            <rewrite-uri template="/api/users/2" />
            <!-- sidecar request -->
            <send-request mode="new" response-variable-name="var1" timeout="20" ignore-error="true">
                <set-url>https://reqres.in/api/unkown/2</set-url>
                <set-method>GET</set-method>
            </send-request>
        </inbound>
        <backend>
            <base />
        </backend>
        <outbound>
            <base />
            <set-body template="none">@{
                var body = context.Response.Body.As<JObject>(true);
                body["var1"] = ((IResponse)context.Variables["var1"]).Body.As<JObject>();
                return body.ToString();
            }</set-body>
        </outbound>
        <on-error>
            <base />
        </on-error>
    </policies>
    

    【讨论】:

    • 实际上,正如我在此处here 所描述的那样,我一次执行两个请求(相同类型,不同环境),我假设这就是您所说的“sidecar request”。
    猜你喜欢
    • 2023-01-28
    • 2011-04-03
    • 2017-03-26
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    • 1970-01-01
    • 2018-10-26
    相关资源
    最近更新 更多