注意:此产品的某些方面处于 Beta 版阶段。Hybrid 安装选项是 GA。要加入 Beta 版计划,请与您的 Apigee 代表联系。

条件参考文档

条件可让 API 代理在运行时动态运行。条件用于定义对 Apigee 处理流水线评估的变量的操作。条件语句是布尔值,其求值始终为 truefalse

Conditions 概览

本部分介绍了利用 Apigee 如何以及在哪使用条件语句。此外,以下部分还介绍了语法:

条件语句的结构

条件语句的基本结构如下:

<Condition>variable.name operator "value"</Condition>

例如:

<Condition>request.verb = "GET"</Condition>

您可以使用 AND 组合多个条件,以便同时执行多个条件。例如,以下条件评估为 true 仅在请求的 URI 与 /statuses 请求的 HTTP 动词 GET

<Condition>(proxy.pathsuffix MatchesPath "/statuses") and (request.verb = "GET")</Condition>

使用条件语句的位置

您可以使用条件来控制以下行为:

政策执行

您可以使用条件语句来控制政策的执行。一个常见的使用场景是基于 HTTP 标头或消息内容进行条件回答转换。

以下示例根据 Accept 标头有条件地将 XML 转换为 JSON:

<Step>
  <Condition>request.header.accept = "application/json"</Condition>
  <Name>XMLToJSON</Name>
</Step>

流执行

您可以使用条件语句来控制 ProxyEndpoints 和 TargetEndpoints 中的指定流的执行。请注意,只可有条件地执行“命名”流程。ProxyEndpoints 和 TargetEndpoints 的预流程和后流程(请求和回答)都针对每个事务执行,因此可提供无条件的“故障安全”功能。

例如,要根据请求消息的 HTTP 动词执行条件请求流程,并根据表示错误的(可能)HTTP 状态代码执行条件响应流:

<Flow name="GetRequests">
  <Condition>request.verb = "GET"</Condition>
  <Request>
    <Step>
      <Condition>request.path MatchesPath "/statuses/**"</Condition>
      <Name>StatusesRequestPolicy</Name>
    </Step>
  </Request>
  <Response>
    <Step>
      <Condition>(response.status.code = 503) or (response.status.code = 400)</Condition>
      <Name>MaintenancePolicy</Name>
    </Step>
  </Response>
</Flow>

目标端点路由选择

您可以使用条件语句来控制由代理端点配置调用的目标端点。路由规则会将请求转发到特定的目标端点。当多个目标端点可用时,路由规则会评估其条件,并且如果为 true,则请求将转发到命名的目标端点。

例如,要根据 Content-Type 有条件地将消息路由到指定的目标端点,请运行以下命令:

<RouteRule name="default">
 <!--this routing executes if the header indicates that this is an XML call. If true, the call is routed to the endpoint XMLTargetEndpoint-->
  <Condition>request.header.Content-Type = "text/xml"</Condition>
  <TargetEndpoint>XmlTargetEndpoint</TargetEndpoint>
</RouteRule>

如需了解详情,请参阅 流变量和条件

路径表达式

路径表达式用于匹配 URI 路径,使用“*”表示单个路径元素,使用“**”表示多个 URI 级别。

例如:

格式 匹配的 URI 路径示例
/*/a/ /x/a//y/a/
/*/a/* /x/a/b/y/a/foo
/*/a/** /x/a/b/c/d
/*/a/*/feed/ /x/a/b/feed//y/a/foo/feed/
/a/**/feed/** /a/b/feed/rss/1234

% 被视为转义字符。模式 %{user%}{user} 匹配,但与 user 不匹配。

变量

您可以在条件语句中使用内置流变量和自定义变量。有关详情,请参阅:

运算符

使用运算符时,请注意以下限制:

  • 运算符不能用作变量名称。
  • 运算符前后必须添加空格字符。
  • 要在变量中包含运算符,变量名称必须括在单引号中。例如 'request.header.help!me'
  • 算术运算符 (+ * - / %) 不受支持。
  • 对于运算符,使用 Java 优先级
  • Apigee 依赖 java.util.regex 中实现的正则表达式。

下表列出了支持的运算符。您可以在表达式中使用符号或单词:

符号 文字 说明
! Notnot 一元运算符(使用单个输入)
= EqualsIs 等于(区分大小写)
!= NotEqualsIsNot 不等于(区分大小写)
:= EqualsCaseInsensitive 相等,但不区分大小写
>&gt; GreaterThan 大于。 如果在 Apigee 界面中定义条件时使用 >,则该函数将转换为 &gt;。
>=&gt;= GreaterThanOrEquals 大于或等于。 如果在 Apigee 界面中定义条件时使用 >=,则该函数将转换为 &gt;=。
&lt; LesserThan 小于。Apigee 界面不支持字面量 <.
&lt;= LesserThanOrEquals 小于或等于。Apigee 界面不支持字面量 <=。
&& Andand
|| Or
() 对表达式进行分组。( 打开表达式,) 会将其关闭。
~~ JavaRegex

javax.util.regex 兼容的正则表达式匹配。该匹配区分大小写。如需查看示例,请参阅 条件语句中的模式匹配

~ MatchesLike 使用“*”通配符字符匹配 glob 样式模式。该匹配区分大小写。如需查看示例,请参阅 使用条件匹配模式
~/ MatchesPathLikePath 匹配路径表达式。该匹配区分大小写。 如需查看示例,请参阅 使用条件匹配模式
=| StartsWith 匹配字符串的第一个字符。该匹配区分大小写。

操作对象

在进行比较之前,Apigee Apigee 会根据常见数据类型调整操作对象。例如,如果响应状态代码为 404,表达式 response.status.code = "400"response.status.code = 400 是等效的。

对于数字操作对象,数据类型会被解释为整数,除非该值按以下方式终止:

  • “f”或“F”(浮点数,例如 3.142f、91.1F)
  • “d”或“D”(双精度型,例如 3.142d、100.123D)
  • “l”或“L”(长,例如,12321421312L)

在这些情况下,系统会执行下表中显示的适配(RHS 指的是等式的右侧,LHS 是左侧):

RHS LHS 布尔值 整数 浮点数 双精度型 字符串 可比较 对象
布尔值 布尔值 整数 浮点数 双精度型 字符串 -
整数 整数 整数 浮点数 双精度型 字符串 可比较 -
浮点数 双精度型 字符串 可比较 -
浮点数 浮点数 浮点数 浮点数 浮点数 双精度型 字符串 可比较 -
双精度型 双精度型 双精度型 双精度型 双精度型 双精度型 字符串 可比较 -
字符串 字符串 字符串 字符串 字符串 字符串 字符串 可比较 -
可比较 可比较 可比较 可比较 可比较 可比较 可比较 可比较 -
对象 - - - - - - - -

Null 操作对象

下表显示了在所显示操作对象的左侧 (LHS) 和/或右侧 (RHS) 中,当值为 null 时的条件是求值为 true 还是 false

运算符 LHS null RHS null LHS 和 RHS null
===:=
=|
!=
>&gt;
>=&gt;=
&lt;
&lt;=
~ 不适用
~~ 不适用
!~
~/ 不适用

字面

除了字符串和数值字面之外,您还可以在条件语句中使用以下字面:

  • null
  • true
  • false

例如:

  • request.header.host is null
  • flow.cachehit is true

示例

<RouteRule name="default">
     <Condition>request.header.content-type = "text/xml"</Condition>
     <TargetEndpoint>XmlTargetEndpoint</TargetEndpoint>
</RouteRule>
<Step>
    <Condition>response.status.code = 503</Condition>
    <Name>MaintenancePolicy</Name>
</Step>
<Flow name="GetRequests">
    <Condition>response.verb="GET"</Condition>
    <Request>
        <Step>
            <Condition>request.path ~ "/statuses/**"</Condition>
            <Name>StatusesRequestPolicy</Name>
        </Step>
    </Request>
    <Response>
        <Step>
            <Condition>(response.status.code = 503) or (response.status.code = 400)</Condition>
            <Name>MaintenancePolicy</Name>
        </Step>
    </Response>
</Flow>