本页面适用于 Apigee 和 Apigee Hybrid。
查看 Apigee Edge 文档。
流变量是可以在政策或实用程序(例如调试工具)中访问的对象。通过这些变量,您可以维护与 Apigee 处理的 API 事务关联的状态。
什么是流变量?
API 代理流的环境中存在流变量,可用来跟踪 API 事务中的状态,就像跟踪软件程序中已命名的变量状态一样。流变量存储如下信息:
- 从发出请求的应用发送的 IP 地址、标头、网址路径和载荷
- 系统信息,例如 Apigee 收到请求的日期和时间
- 政策执行时派生的数据。例如,在验证 OAuth 令牌的政策执行后,Apigee 会创建流变量来保存请求应用的名称等信息。
- 来自目标系统的响应的相关信息
一些变量内置在 Apigee 中,并且在接收 API 请求时自动填充。您可以在整个 API 事务中找到这些变量。您还可以使用 AssignMessage 政策等政策创建自己的自定义变量,或在 JavaScript 和 Java 代码中创建。
如您所见,变量的范围也有限制,可在哪些位置访问变量取决于变量在 API 代理流中的创建时间。通常,在创建变量后,它可供稍后在 API 事务流中执行的所有政策和代码使用。
如何使用流变量?
- 政策可以从流变量中检索状态,并使用流变量来完成工作。
例如,VerifyJWT 政策可以从流变量检索要验证的令牌,然后验证令牌。再举一例,JavaScript 政策可以检索流变量并对这些变量中包含的数据进行编码。
- 条件流可以引用流变量,以通过 Apigee 定向 API 流,这与 switch 语句在编程中的工作方式类似。
例如,用于返回故障的政策仅在设置了特定流变量时执行。
让我们通过几个示例来了解如何在这些上下文中使用变量。
政策中的流变量
一些政策将流变量作为输入。
例如,以下 AssignMessage 政策采用流变量 client.ip
的值,并将其放在名为 My-Client-IP
的请求标头中。如果已在请求流中添加此政策,则此政策会设置传递给后端目标的标头。如果已在响应流上设置此政策,则系统会将标头发送回客户端应用。
<AssignMessage name="set-ip-in-header"> <AssignTo createNew="false" transport="http" type="request">request</AssignTo> <Set> <Headers> <Header name="My-Client-IP">{client.ip}</Header> </Headers> </Set> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> </AssignMessage>
在另一个示例中,当配额政策执行时,系统会使用与政策相关的值填充多个流变量。其中一个变量名为 ratelimit.my-quota-policy.used.count
(其中,my-quota-policy
是您感兴趣的配额政策的名称)。
您可以稍后执行条件流,即“如果当前配额计数低于上限值的 50% 且发生在上午 9 点到下午 5 点之间,则系统会强制执行不同的配额。”此条件可能依赖于当前配额计数的值和名为 system.time
的流变量(一种内置 Apigee 变量)。
条件流中的流变量
条件流可用来评估流变量并可让代理动态运行。条件通常用于更改流的行为、步骤和路由规则。
下面是一个条件流,用来评估代理流步骤中变量 request.verb
的值。在这种情况下,如果请求动词是 POST,则会执行 VerifyAPIKey 政策。这是 API 代理配置中使用的一种常见模式。
<PreFlow name="PreFlow"> <Request> <Step> <Condition>request.verb equals "POST"</Condition> <Name>VerifyApiKey</Name> </Step> </Request> </PreFlow>
现在,您可能想知道 request.verb
、client.ip
和 system.time
等变量来自哪里?何时实例化这些变量并使用值进行填充?如需帮助您了解变量的创建时间以及何时可供您使用,请参阅直观呈现 API 代理流。
使用 JavaScript 政策调用的 JavaScript 代码中的流变量
借助 JavaScript 政策,您可以在 API 代理流的环境中执行 JavaScript 代码。此政策执行的 JavaScript 使用 Apigee JavaScript 对象模型,该模型可让您的自定义代码访问与执行该代码所在的 API 代理流相关的请求、响应和上下文对象。例如,此代码使用从流变量 target.name 获取的值设置响应标头。
context.setVariable("response.header.X-Apigee-Target", context.getVariable("target.name"));
使用 JavaScript 读取和设置变量的技术与使用 AssignMessage 政策执行的工作(如上所示)类似。这只是在 Apigee 上完成相同操作的另一种方法。需要记住的关键一点是,通过 JavaScript 政策执行的 JavaScript 有权访问 API 代理流中存在且位于范围内的所有流变量。
直观呈现 API 代理流
要了解流变量的范围,请务必了解或直观呈现消息通过 API 代理的方式。API 代理包含一系列以流形式整理的消息处理步骤。在代理流的每个步骤中,代理都会评估步骤可用的信息并决定后续操作。在此过程中,代理可以执行政策代码或执行条件拆分。
下图演示了这一系列流。请注意,这些流由四个主要片段组成:ProxyEndpoint 请求、TargetEndpoint 请求、TargetEndpoint 响应和 ProxyEndpoint 响应。
随着我们完成本主题的其余部分来开始探索流变量时,请记住这种流结构。
变量范围与代理流有何关联
如上文所述,只要您可以直观呈现消息如何流经代理,就可以立即开始了解变量的范围。范围指的是在首次实例化某个变量时代理流生命周期中的时间点。
例如,如果您将某个政策附加到 ProxyEndpoint 请求片段,则该政策将无法访问范围限于 TargetEndpoint 请求片段的任何变量。这是因为流的 TargetEndpoint 请求片段尚未执行,因此 API 代理还没有机会填充该范围内的变量。
下表列出了完整的变量范围集,并指明在代理流中变量何时可用。
变量范围 | 这些变量的填充位置 |
---|---|
代理请求 | ProxyEndpoint 请求片段 |
目标请求 | TargetEndpoint 请求片段 |
目标响应 | TargetEndpoint 响应片段 |
代理响应 | ProxyEndpoint 响应片段 |
随时提供 | 代理收到请求后立即执行。这些变量在整个代理流生命周期内都可用。 |
例如,有一个名为 client.ip
的内置 Apigee 变量。此变量具有代理请求范围。其中会自动填充调用该代理的客户端的 IP 地址。当某个请求首次进入 ProxyEndpoint 时,系统会填充该变量,且变量在代理流的整个生命周期内都可用。
还有一个名为 target.url
的内置变量。此变量的范围为目标请求。在 TargetEndpoint 请求片段中,该变量中将填充传送给后端目标的请求网址。如果您尝试访问 ProxyEndpoint 请求片段中的 target.url
,您将收到 NULL
值。如果您尝试在此变量限定范围之前先设置此变量,则该代理不会执行任何操作,即不会生成错误,也不会设置变量。
下面是一个简单的示例,演示了如何考虑变量范围。假设您要复制请求对象的全部内容(标头、参数、正文),并将其分配给要发送回调用应用的响应载荷。您可以使用 AssignMessage 政策来完成此任务。政策代码如下所示:
<AssignMessage name="CopyRequestToResponse"> <AssignTo type="response" createNew="false">response</AssignTo> <Copy source="request"/> </AssignMessage>
此政策只会复制 request
对象,并将其分配给 response
对象。但此政策在代理流中应放置在哪些位置?答案是必须将它置于 TargetEndpoint 响应中,因为响应变量的范围为“目标响应”。
引用流变量
Apigee 中的所有内置变量均遵循点表示法命名惯例。此惯例可让您更轻松地确定变量的用途。例如 system.time.hour
和 request.content
。
Apigee 保留各种前缀以适当地整理相关变量。这些前缀包括:
request
response
system
target
如需引用政策中的变量,请用大括号括住该变量。例如,以下 AssignMessage 政策采用变量 client.ip
的值,并将其放在名为 Client-IP
的请求标头中。
<AssignMessage name="set-ip-in-header"> <AssignTo createNew="false" transport="http" type="request">request</AssignTo> <Set> <Headers> <Header name="Client-IP">{client.ip}</Header> </Headers> </Set> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> </AssignMessage>
在条件流中,不需要使用大括号。以下条件示例将评估变量 request.header.accept
:
<Step> <Condition>request.header.accept = "application/json"</Condition> <Name>XMLToJSON</Name> </Step>
您还可以引用 JavaScript 和 Java 代码中的流变量。有关详情,请参阅:
流变量的数据类型
流变量的每个属性都具有明确定义的数据类型,例如字符串、长整数、整数、布尔值或集合。您可以找到流变量参考文档中列出的数据类型。对于政策创建的变量,请参阅具体的政策参考主题以了解数据类型信息。
您手动创建的变量采用创建它们时指定的类型,具体取决于允许的值类型。
在政策中使用流变量
许多政策会在正常执行过程中创建流变量。政策参考文档记录了所有这些政策专用变量。
在使用代理和政策时,请务必查看政策参考文档,以了解创建的变量以及变量的用途。例如,配额政策会创建一组变量,其中包含配额计数和限制以及到期时间等相关信息。
某些政策变量对于调试非常有用。例如,您可以使用 调试工具来查看在代理流中的特定实例上设置了哪些变量。
借助 ExtractVariables 政策,您可以使用从消息中提取的数据填充自定义变量。您可以提取查询参数、标头和其他数据。例如,您可以使用模式解析请求和响应消息,以从消息中提取特定数据。
在以下示例中,ExtractVariables 政策会解析响应消息并存储从响应中获取的特定数据。该政策会创建两个自定义变量(geocoderesponse.latitude
和 geocoderesponse.longitude
)并为其赋值。
<ExtractVariables name="ParseGeocodingResponse"> <Source>response</Source> <VariablePrefix>geocoderesponse</VariablePrefix> <JSONPayload> <Variable name="latitude"> <JSONPath>$.results[0].geometry.location.lat</JSONPath> </Variable> <Variable name="longitude"> <JSONPath>$.results[0].geometry.location.lng</JSONPath> </Variable> </JSONPayload> </ExtractVariables>
同样,请注意许多政策会自动创建变量。您可以在代理流上下文中访问这些变量,其具体记录在每个政策主题下的政策参考文档中。
在 JavaScript 代码中使用流变量
您可以在 API 代理的环境中执行的 JavaScript 代码中直接访问和设置变量。通过 Apigee JavaScript 对象模型,在 Apigee 上执行的 JavaScript 可以直接访问代理流变量。
要访问 JavaScript 代码中的变量,请针对以下任何对象调用 getter/setter 方法:
context
proxyRequest
proxyResponse
targetRequest
targetResponse
如您所见,这些对象引用映射到代理流模型中熟悉的片段,如前面的直观呈现 API 代理流所述。
context
对象对应于“全局”可用变量,例如系统变量。例如,您可以对 context
对象调用 getVariable()
以获取当前年份:
var year = context.getVariable('system.time.year');
同样,您可以调用 setVariable()
来设置自定义变量的值或任意开箱即用的可写变量的值。在这里,我们将创建一个名为 organization.name.myorg
的自定义变量并为其赋值。
var org = context.setVariable('organization.name.myorg', value);
由于此变量是使用 context
对象创建的,因此它可用于所有流片段(实质上类似于创建全局变量)。
您还可以在使用 JavaCallout 政策执行的 Java 代码中获取或设置代理流变量。
注意事项
以下是有关流变量的几个重要注意事项:
- 某些“开箱即用”out-of-the-box的变量由代理本身自动实例化并填充。这些变量记录在流变量参考文档中。
- 您可以创建可在代理流中使用的自定义变量。可以使用 AssignMessage 政策和 JavaScript 政策等政策创建变量。
- 变量具有范围。例如,当第一个代理收到来自应用的请求时,系统会自动填充某些变量。其他变量会在代理的响应流片段中进行填充。这些响应变量在响应片段执行之前保持未定义状态。
- 政策执行时,它们可以创建和填充政策专用变量。每项政策的文档都会列出所有这些相关的政策专用变量。
- 条件流通常用于评估一个或多个变量。如果您想创建条件流,则需要了解变量。
- 许多政策都使用变量作为输入或输出。一个政策创建的变量随后可能被另一个政策使用。