如何在 APIGEE 的 JSON AssignMessage 负载中省略空值?
How to omit null values in JSON AssignMessage payload in APIGEE?
我构建了一个代理,它基本上期望 JSON 输入对象与最终端点期望接收的输入对象不同。因此,为了将请求对象从一个对象桥接到另一个对象,我使用 AssingMessage 策略来转换 json 输入。
我正在做这样的事情:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="Assign-Message-Sample">
<DisplayName>Assign Message-Sample</DisplayName>
<Remove>
<Headers>
<Header name="login_id"/>
<Header name="Authorization"/>
</Headers>
<Payload>true</Payload>
</Remove>
<Set>
<Payload contentType="application/json">
{
"valueA": "{clientrequest.valueA}",
"valueB": "{clientrequest.valueB}",
"valueC": "{clientrequest.valueC}",
"valueD": "{clientrequest.valueD}",
"valueE": "{clientrequest.valueE}",
"valueF": "{clientrequest.valueF}",
}
</Payload>
<Verb>POST</Verb>
</Set>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>
当一些值是空的时候就会出现问题。目标服务器无法正确处理任何空值(脱离我的控制)。
我的问题是:如果值为空,我如何才能完全跳过一个参数?
我正在寻找这样的东西(或更好的替代品):
<Payload contentType="application/json">
{
<skip-if-empty name="clientrequest.valueA">
"valueA": "{clientrequest.valueA}",
</skip-if-empty>
"valueB": "{clientrequest.valueB}",
...
}
</Payload>
根据我的研究发现,这似乎是一项 Javascript 政策的工作。
这是怎么做到的?
您基本上需要在 AssignMessage 执行之前放置一个 javascript 策略。在 javascript 策略中,如果未提供值,您可以自由应用所有逻辑来忽略某些参数。
例如,假设我们已经使用 ExtractVariables 策略将请求值提取到变量中。然后,在 Javascript 策略中,我们可以验证这些值并构建生成的 JSON 对象,稍后将其存储在另一个变量中,该变量将由 AssingMessage 策略选取。
javascript 政策:
var valueA = context.getVariable("clientrequest.valueA"),
valueB = context.getVariable("clientrequest.valueB"),
valueC = context.getVariable("clientrequest.valueC"),
...
var result = {};
if(valueB) {
result.b = valueB;
}
if(valueA) {
result.a = valueA;
}
if(valueC) {
result.c = valueC;
}
...
context.setVariable("newInput", JSON.stringify(result));
然后我们的 AssignMessage 将只获取我们刚刚存储的变量:"newInput",它将包含完整的 JSON 对象字符串:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="Assign-Message-Sample">
<DisplayName>Assign Message-Sample</DisplayName>
<Remove>
<Headers>
<Header name="login_id"/>
<Header name="Authorization"/>
</Headers>
<Payload>true</Payload>
</Remove>
<Set>
<Payload contentType="application/json">
{newInput}
</Payload>
<Verb>POST</Verb>
</Set>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>
这个解决方案对我来说效果很好。我希望其他人觉得它有用。
我构建了一个代理,它基本上期望 JSON 输入对象与最终端点期望接收的输入对象不同。因此,为了将请求对象从一个对象桥接到另一个对象,我使用 AssingMessage 策略来转换 json 输入。
我正在做这样的事情:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="Assign-Message-Sample">
<DisplayName>Assign Message-Sample</DisplayName>
<Remove>
<Headers>
<Header name="login_id"/>
<Header name="Authorization"/>
</Headers>
<Payload>true</Payload>
</Remove>
<Set>
<Payload contentType="application/json">
{
"valueA": "{clientrequest.valueA}",
"valueB": "{clientrequest.valueB}",
"valueC": "{clientrequest.valueC}",
"valueD": "{clientrequest.valueD}",
"valueE": "{clientrequest.valueE}",
"valueF": "{clientrequest.valueF}",
}
</Payload>
<Verb>POST</Verb>
</Set>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>
当一些值是空的时候就会出现问题。目标服务器无法正确处理任何空值(脱离我的控制)。
我的问题是:如果值为空,我如何才能完全跳过一个参数?
我正在寻找这样的东西(或更好的替代品):
<Payload contentType="application/json">
{
<skip-if-empty name="clientrequest.valueA">
"valueA": "{clientrequest.valueA}",
</skip-if-empty>
"valueB": "{clientrequest.valueB}",
...
}
</Payload>
根据我的研究发现,这似乎是一项 Javascript 政策的工作。
这是怎么做到的?
您基本上需要在 AssignMessage 执行之前放置一个 javascript 策略。在 javascript 策略中,如果未提供值,您可以自由应用所有逻辑来忽略某些参数。
例如,假设我们已经使用 ExtractVariables 策略将请求值提取到变量中。然后,在 Javascript 策略中,我们可以验证这些值并构建生成的 JSON 对象,稍后将其存储在另一个变量中,该变量将由 AssingMessage 策略选取。
javascript 政策:
var valueA = context.getVariable("clientrequest.valueA"),
valueB = context.getVariable("clientrequest.valueB"),
valueC = context.getVariable("clientrequest.valueC"),
...
var result = {};
if(valueB) {
result.b = valueB;
}
if(valueA) {
result.a = valueA;
}
if(valueC) {
result.c = valueC;
}
...
context.setVariable("newInput", JSON.stringify(result));
然后我们的 AssignMessage 将只获取我们刚刚存储的变量:"newInput",它将包含完整的 JSON 对象字符串:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="Assign-Message-Sample">
<DisplayName>Assign Message-Sample</DisplayName>
<Remove>
<Headers>
<Header name="login_id"/>
<Header name="Authorization"/>
</Headers>
<Payload>true</Payload>
</Remove>
<Set>
<Payload contentType="application/json">
{newInput}
</Payload>
<Verb>POST</Verb>
</Set>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>
这个解决方案对我来说效果很好。我希望其他人觉得它有用。