使用流变量

您正在查看 Apigee Edge 文档。
前往 Apigee X 文档
信息

从概念上讲,流变量是您可以从政策或实用程序(例如 Trace 工具)中访问的对象。通过这些变量,您可以维护与 Apigee Edge 处理的 API 事务关联的状态。

什么是流变量?

API 代理流的环境中存在流变量,可用来跟踪 API 事务中的状态,就像跟踪软件程序中已命名的变量状态一样。流变量存储如下信息:

  • 从发出请求的应用发送的 IP 地址、标头、网址路径和载荷
  • 系统信息,例如 Edge 收到请求的日期和时间
  • 政策执行时派生的数据。例如,在政策执行验 OAuth 令牌的操作后,Edge 会创建流变量来保存发出请求的应用名称等信息。
  • 来自目标系统的响应的相关信息

一些变量“内置”在 Edge 中,会在收到 API 请求时自动填充。您可以在整个 API 事务中找到这些变量。您还可以使用 AssignMessage 政策等政策创建自己的自定义变量,或在 JavaScript、Node.js 和 Java 代码中创建。

如您所见,变量的范围也有限制,可在哪些位置访问变量取决于变量在 API 代理流中的创建时间。通常,在创建变量后,它可供稍后在 API 事务流中执行的所有政策和代码使用。

如何使用流变量?

政策条件流中使用了流变量:

  • 政策可以从流变量中检索状态,并使用流变量来完成工作。

    例如,VerifyJWT 政策可以从流变量检索要验证的令牌,然后验证令牌。再举一例,JavaScript 政策可以检索流变量并对这些变量中包含的数据进行编码。

  • 条件流可以引用流变量以通过 Edge 定向 API 流,这与 switch 语句在编程中的工作方式类似。

    例如,用于返回故障的政策仅在设置了特定流变量时执行。最后,您可以在 Node.js 目标应用中获取和设置流变量。

让我们通过几个示例来了解如何在这些上下文中使用变量。

政策中的流变量

一些政策将流变量作为输入。

例如,以下 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(一种内置的 Edge 变量)。

条件流中的流变量

条件流可用来评估流变量并可让代理动态运行。条件通常用于更改流的行为、步骤和路由规则。

下面是一个条件流,用来评估代理流步骤中变量 request.verb 的值。在这种情况下,如果请求动词是 POST,则会执行 VerifyAPIKey 政策。这是 API 代理配置中使用的一种常见模式。

<PreFlow name="PreFlow">
    <Request>
        <Step>
            <Condition>request.verb equals "POST"</Condition>
            <Name>VerifyApiKey</Name>
        </Step>
    </Request>
</PreFlow>

现在,您可能想知道 request.verbclient.ipsystem.time 等变量来自哪里?何时实例化这些变量并使用值进行填充?为了帮助您了解变量的创建时间以及何时可供您使用,请参阅了解流变量范围

使用 JavaScript 政策调用的 JavaScript 代码中的流变量

借助 JavaScript 政策,您可以在 API 代理流的环境中执行 JavaScript 代码。此政策执行的 JavaScript 使用 Apigee JavaScript 对象模型,该模型可让您的自定义代码访问与执行该代码所在的 API 代理流相关的请求、响应和上下文对象。例如,此代码使用从流变量 target.name 获取的值设置响应标头。

context.setVariable("response.header.X-Apigee-Target", context.getVariable("target.name"));

使用 JavaScript 读取和设置变量的技术与使用 AssignMessage 政策执行的工作(如上所示)类似。这是在 Edge 中完成相同事情所采用的另一种方法。需要记住的关键一点是,通过 JavaScript 政策执行的 JavaScript 有权访问 API 代理流中存在且位于范围内的所有流变量。

Node.js 代码中的流变量

通过要求使用 apigee-access 模块,您可以在部署到 Edge 的 Node.js 代码中设置和访问流变量。

下面是一个简单的示例,其中名为 custom.foo 的变量设置为值 Bar。设置完毕后,此新变量可供在 Node.js 代码执行后代理流中发生的任何政策或其他代码使用。

var http = require('http');
var apigee = require('apigee-access');

http.createServer(function (request, response) {
  apigee.setVariable(request, "custom.foo", "Bar");
  response.writeHead(200, {'Content-Type': 'text/plain'});
  response.end('Hello World\n');
}).listen(8124);

console.log('Server running at http://127.0.0.1:8124/');

如需详细了解如何使用 apigee-access 处理变量,请参阅在 Node.js 中访问流变量

了解流变量范围

变量作用域与 API 代理调用的流或整体“生命周期”相关。

直观呈现 API 代理流

要了解流变量的范围,请务必了解或直观呈现消息通过 API 代理的方式。API 代理包含一系列以流形式整理的消息处理步骤。在代理流的每个步骤中,代理都会评估步骤可用的信息并决定后续操作。在此过程中,代理可以执行政策代码或执行条件拆分

下图演示了这一系列流。请注意,这些流由四个主要片段组成:ProxyEndpoint 请求、TargetEndpoint 请求、TargetEndpoint 响应和 ProxyEndpoint 响应

随着我们完成本主题的其余部分来开始探索流变量时,请记住这种流结构。

变量范围与代理流有何关联

如上文所述,只要您可以直观呈现消息如何流经代理,就可以立即开始了解变量的范围。范围指的是在首次实例化某个变量时代理流生命周期中的时间点。

例如,如果您将某个政策附加到 ProxyEndpoint 请求片段,则该政策将无法访问范围限于 TargetEndpoint 请求片段的任何变量。这是因为流的 TargetEndpoint 请求片段尚未执行,因此 API 代理还没有机会填充该范围内的变量。

下表列出了完整的变量范围集,并指明在代理流中变量何时可用。

变量范围 这些变量的填充位置
代理请求 ProxyEndpoint 请求片段
目标请求 TargetEndpoint 请求片段
目标响应 TargetEndpoint 响应片段
代理响应 ProxyEndpoint 响应片段
随时提供 代理收到请求后立即执行。这些变量在整个代理流生命周期内都可用。

举例来说,有一个名为 client.ip 的内置 Edge 变量。此变量具有“代理请求”范围。其中会自动填充调用该代理的客户端的 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 Edge 中的所有内置变量均遵循点表示法命名惯例。此惯例可让您更轻松地确定变量的用途。例如 system.time.hourrequest.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 代码中的流变量。如需了解详情,请参阅:

流变量的数据类型

流变量的每个属性都具有明确定义的数据类型,例如字符串、长整数、整数、布尔值或集合。您可以找到流变量参考文档中列出的数据类型。对于政策创建的变量,请参阅具体的政策参考主题以了解数据类型信息。

您手动创建的变量会假定其创建时指定的类型,并取决于允许使用的值的类型。例如,在 Node.js 代码中创建的变量仅限于 Number、String、Boolean、null 或 undefined。

在政策中使用流变量

许多政策会在正常执行过程中创建流变量。政策参考文档记录了所有这些政策专用变量。

在使用代理和政策时,请务必查看政策参考文档,以了解创建的变量以及变量的用途。例如,配额政策会创建一组变量,其中包含配额计数和限额以及到期时间等相关信息。

某些政策变量对于调试非常有用。例如,您可以使用 Trace 工具来查看在代理流中的特定实例上设置了哪些变量。

借助 ExtractVariables 政策,您可以使用从消息中提取的数据填充自定义变量。您可以提取查询参数、标头和其他数据。例如,您可以使用模式解析请求和响应消息,以从消息中提取特定数据。

在以下示例中,“提取变量”会解析响应消息并存储从响应中获取的特定数据。该政策会创建两个自定义变量(geocoderesponse.latitudegeocoderesponse.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 对象模型,在 Edge 上执行的 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 代码中获取/设置代理流变量。

在 Node.js 应用中访问流变量

您可以从部署到 Edge 的 Node.js 代码中获取、设置和删除流变量。您只需在代码中“require”apigee-access 模块即可。如需了解详情,请参阅在 Node.js 中访问流变量

注意事项

以下是有关流变量的几个重要注意事项:

  • 某些“开箱即用”变量由代理本身自动进行实例化并填充。这些变量记录在流变量参考文档中。
  • 您可以创建可在代理流中使用的自定义变量。您可以使用 AssignMessage 政策JavaScript 政策等政策创建变量,也可以在 Node.js 代码中创建变量。
  • 变量具有范围。例如,当第一个代理收到来自应用的请求时,系统会自动填充某些变量。其他变量会在代理的响应流片段中进行填充。这些响应变量在响应片段执行之前保持未定义状态。
  • 政策执行时,它们可以创建和填充政策专用变量。每项政策的文档都会列出所有这些相关的政策专用变量。
  • 条件流通常用于评估一个或多个变量。如果您想创建条件流,则需要了解变量。
  • 许多政策都使用变量作为输入或输出。一个政策创建的变量随后可能被另一个政策使用。
  • 您可以使用纯 JavaScript(以及我们的 JavaScript 对象模型)或在 Edge 上执行代码的 JavaCallout 政策,从 Node.js 中获取和设置许多流变量。

相关代码示例

API 代理示例位于 GitHub 上,易于下载和使用。如需了解如何下载和使用示例,请参阅使用 API 代理示例。如需了解 API 代理示例及其作用的说明,请参阅示例列表

使用变量和变量处理的代理示例包括:

  • variables - 演示如何根据传输、JSON 和 XML 消息内容提取和设置变量。
  • policy-mashup-cookbook - 一个完整的应用,它使用政策组合调用两个公共 API、合并结果,并为客户端应用生成丰富的响应。如需详细了解此示例,请参阅使用政策组合
  • conditional-policy - 根据变量值实现简单的条件政策实施。

相关主题

  • 流变量参考文档中列出了自动填充 API 代理的所有变量。该文档中还列出了每个变量的类型和范围。
  • 如需了解特定政策填充哪些变量,请参阅该政策对应的参考主题。例如,请参阅配额政策参考文档中的流变量