仅 DataPower API Gateway

正在编写切换条件脚本- DataPower API Gateway

您可以使用 JSONata 表达式语言在 DataPower® API Gateway 中为 switch 策略编写条件脚本。

必须先解析消息的有效内容,然后才能在切换策略条件中使用 JSONata。 因此,解析策略必须在交换机策略之前。 然后,可以对存储在输出变量的 body 字段中的已解析内容使用 JSONata 条件。 默认变量是 message。 例如,如果输出变量为 message,那么可以对解析的内容使用 JSONata 条件 $exists(message.body.username)

JSONata 在 API Connect

API Connect 支持 JSONata 规范中的 ` v2.0 `,但存在以下限制:

  • 如果您使用 JSONata 表达式来提取或屏蔽字段,即使这些字段位于不同位置,其软链接副本也会受到“提取”或“屏蔽”策略的影响。
  • API Connect 不支持高阶 JSONata 函数(即处理其他函数的函数)。
  • 如果由 支持的 API Connect JSONata 函数将一个高阶函数作为参数调用,则该参数不被支持(因为不支持高阶函数)。
  • 以下 JSONata v2.0 函数不被支持:
    • $eval()
    • $sift()
    • $each()
    • $error()
    • $assert()
  • $fromMillis() 支持该功能,但受以下限制:
    • $fromMillis() 参数支持的数值范围为 -5364662400000 至 2903299199000。
      • 小于 -5364662400000 的数值将使用 -5364662400000。 换句话说,报告的时间戳为 1800-01-01T00:00:00Z。
      • 大于 2903299199000 的数值将使用 2903299199000。 换句话说,报告的时间戳为 2261-12-31T23:59:59Z。
  • $now() 支持该功能,但受以下限制:
    • 不支持以下组件限定符:
      • W = 年度第几周
      • w = 月份中的星期
      • X = ISO 年度周编号
      • x = ISO 周编号月
    • 不支持将数字转换为文字,因此以下格式修饰符不被支持:
      • W = 大写单词(例如:[YW] => 两千零二十四)
      • w = 小写单词(例如:[Yw] => 2024)
      • Ww = 首字母大写(例如:[YWw] => 2024)
    • 错误信息是通用的。

表 1 列出了可在标准 JSONata 语法中使用的功能扩展。 每个扩展对应于 API 上下文的一部分。

表 1. JSONata 的功能扩展
分机 变量 描述
$apiCtx() 对 API 上下文的通用访问 $apiCtx() 扩展提供了对 API 上下文的通用访问。
  • 提取操作中的示例转换字段:
    "$apiCtx().request.uri"
  • 开关操作中某案例的示例条件:
    "$apiCtx().request.path = '/simple/apictx-function'"
$header(name) message.headers.name 消息头
$httpVerb() request.verb 请求的 HTTP 方法
$operationID() api.operation.id 操作标识
$operationPath() api.operation.path 操作路径
$queryParameter('name')
  • request.parameters.name.locations

    支持的关键词是 query

  • request.parameters.name.values
在 中搜索 query request.parameters.name.locations 的索引,并返回 request.parameters.name.values[index],其中 [index] 是在 个位置 query 中 的值。 参数值不是解码的 URL。
$statusCode() message.status.code 状态码
$storageType([arg]) variable.body

您可在 API 上下文中指定任意变量。 不指定任何变量时,将使用缺省变量 message.body

消息的存储类型。 受支持的值为 binaryemptygraphqljsonstreamxml
$urlParameter('name')
  • request.parameters.name.locations

    支持的关键词是 pathquery

  • request.parameters.name.values
在 中搜索 和 request.parameters.name.locations path 的索引,并返回一个 query 包含 和 pathquery 中的值的单一 request.parameters.name.values数组。 在 URL 包含 path 和 query 参数值时,数组先包含 path 值,后跟 query 值。 按照接收顺序添加每个参数类型的值。 参数值为解码的 URL。
例如,以下链接 URL 同时包含路径和查询参数的值。
http://example.com/petstore/cats/adopt?breed=Sphynx&breed=Siamese
$urlParameter('breed')URL 返回以下数组。
[cats, adopt, Sphynx, Siamese]

在此示例中,URL 包含配置为 /petstore/{breed}/{breed} 的 API 路径,其中,breed 配置为 API 路径的 path 参数。 因此,catsadopt 包含在输出中。

$xpath(path, xpathExpression) 您可在 API 上下文中指定任意可写变量。 xpathExpression 必须为文字串。 允许使用 XPath 表达式。 以下示例指定了源文件中的所有价格元素。
$xpath($, '//price')

表 2 列出了可用于 GraphQL API 的功能扩展。

表 2. GraphQL 版 JSONata 的功能扩展
分机 变量 描述
$gqlActiveOperation([graphql_message]) message.body 获取在指定的 GraphQL 消息中找到的当前操作。 该名称 operationName 必须与当前操作的名称一致。
$gqlAlias(graphql_field_node) message.body 获取 GraphQL 字段节点的别名。
$gqlFragments([graphql_message]) message.body 获取在指定的 GraphQL 消息中找到的分片。
$gqlName([graphql_node]) message.body 获取节点名称。 对于操作而言,节点名称是 operationName. 对于字段、片段定义、参数和其他元素,节点名称即为该元素的名称。 默认情况下,将检索 message.bodyoperationName
$gqlOperations([graphql_message]) message.body 获取指定 GraphQL 消息中包含的操作。
$gqlType([graphql_node]) message.body 对于查询、变异和订阅这三种查询类型,将检索当前操作的操作类型。
除了函数扩展外,您还可以使用以下运算符:
  • 您可以使用 & (连接) 导航运算符。

您可以使用以下 JSONata 数字运算符:

  • + (补充)
  • - (减)
  • * (乘法)
  • /(除)
  • %(取模)

您可以对数字值或字符串使用以下 JSONata 比较运算符:

  • =
  • !=
  • <
  • >
  • <=
  • >=
您还可以使用以下运算符和表达式。
  • 使用圆括号将序列转换为数组、指定运算符优先级,或对上下文值进行复杂表达式的计算。
  • 数组范围和谓词表达式。
  • 单星号 (*) 和双星号 (**) 通配符。
GraphQL 查询中的以下元素可以使用所示语法以 JSONata 表示法呈现。
  • query

    完整的 GraphQL 查询,包括操作和片段。

  • operationName

    对于匿名操作, operationName 该字段可以为空。

  • ~fragmentSpreadName
  • on~typeCondition
  • ~~fragmentDefinitionName

简单条件语句

以下示例显示使用单个函数的条件。

此示例使用 $httpVerb() 扩展来指定请求的 HTTP 方法。
$httpVerb()="GET"
此示例使用 $operationPath() 扩展来指定操作路径。
$operationPath()="/base/path-2"
此示例使用 $operationID() 扩展来指定操作标识。
$operationID()="test-gatewayscript-GET"
此示例使用 $statusCode() 扩展来指定消息状态码。
$statusCode()=200
此示例使用 $header(name) 扩展来指定消息头的 Content-Type。
$header("Content-Type")="application/json"

使用逻辑运算符组合条件

可以使用 andor 运算符将多个函数组合在一个条件中。

该示例指定 HTTP GET 请求,并且 API 操作路径等于 test-gatewayscript-GET
$httpVerb()="GET" and $operationPath()="test-gatewayscript-GET"
该示例指定 POSTPUT 请求。
$httpVerb()="POST" or $httpVerb()="PUT"
该示例指定 API 操作标识等于 test-gatewayscript_POST 并且消息状态码等于 200,或者 API 操作标识等于 test-gatewayscript-GET 并且消息状态码等于 500
($operationID()="test-gatewayscript-POST" and $statusCode()=200) or ($operationID()="test-gatewayscript-GET" and $statusCode()=500)
该示例指定 API 操作标识等于 test-gatewayscript-POST,消息状态码等于 200 并且 API 操作路径等于 /base/path-2
($operationID()="test-gatewayscript-POST" and $statusCode()=200) and $operationPath()="/base/path-2"
该示例指定消息头内容类型等于 text/plain 并且消息头长度等于 300 或消息状态码等于 200
($header("Content-Type")="text/plain" and $header("Content-Length")=300) or $statusCode()= 200
注意: 当用户通过工具包登录路径(即包含 的 URL?from=TOOLKIT)登录时,生成的 API 密钥的有效期(TTL)固定为 5 分钟。

switch 策略示例

- switch:
  version: 2.0.0
  title: switch
  case:
    - condition: ($statusCode() = 200)
      execute:
        - invoke:
          title: invoke
          timeout: 60
          verb: GET
          cache-response: protocol
          cache-ttl: 900
          target-url: 'https://example.com/1'
    - condition: ($statusCode() != 200 and ($httpVerb() = 'GET' or $httpVerb() = 'PUT'))
      execute:
        - invoke:
          title: invoke
          timeout: 60
          verb: GET
          cache-response: protocol
          cache-ttl: 900
          target-url: 'https://example.com/2'
    - otherwise:
      - set-variable:
        title: set-variable
        actions:
          - set: message.body
            value: Default result
            description: 'Set the default result for the otherwise case'