DataPower API Gateway
only

Writing switch condition scripts - DataPower API Gateway

You write condition scripts for the switch policy in the DataPower® API Gateway by using the JSONata expression language.

The payload of the message must be parsed before you can use JSONata in a switch policy condition. Therefore, a parse policy must precede the switch policy. You can then use a JSONata condition on the parsed content that is stored in the body field of the output variable. The default variable is message. For example, if the output variable is message, you can use the JSONata condition $exists(message.body.username) on the parsed content.

JSONata support in API Connect

API Connect supports v2.0 of the JSONata specification, with the following limitations:

  • If you use a JSONata expression to extract or redact fields, soft linked copies of the field are also affected by the Extract or Redaction policy, even if the fields exist in different locations.
  • API Connect does not support higher order JSONata functions (functions that process other functions).
  • If a JSONata function supported by API Connect calls a higher order function as an argument, that argument is not supported (due to the lack of support for higher order functions).
  • The following JSONata v2.0 functions are not supported:
    • $eval()
    • $formatNumber()
    • $formatInteger()
    • $parseInteger()
    • $sift()
    • $each()
    • $error()
    • $assert()
    • $fromMillis()
  • $now() is supported with the following restrictions:
    • The following component specifiers are not supported:
      • W = Week in year
      • w = Week in month
      • X = ISO week-numbering year
      • x = ISO week-numbering month
    • Representing numbers as words are not supported, so the following presentation modifiers are not supported:
      • W = Uppercase word (for example: [YW] => TWO THOUSAND AND TWENTY-FOUR)
      • w = Lowercase word (for example: [Yw] => two thousand and twenty-four)
      • Ww = Title case word (for example: [YWw] => Two Thousand and Twenty-Four)
    • Error messages are generic.

Table 1 lists the functional extensions that you can use with standard JSONata notation. Each extension corresponds to a part of the API context.

Table 1. Functional extensions to JSONata
Extension Variable Description
$apiCtx() Generic access to an API context The $apiCtx() extension gives generic access to an API context.
  • Sample transform field in an extract action:
    "$apiCtx().request.uri"
  • Sample condition of a case in a switch action:
    "$apiCtx().request.path = '/simple/apictx-function'"
$header(name) message.headers.name Message header
$httpVerb() request.verb HTTP method of the request
$operationID() api.operation.id ID of the operation
$operationPath() api.operation.path Path of the operation
$queryParameter('name')
  • request.parameters.name.locations

    The supported keyword is query.

  • request.parameters.name.values
Searches for the index of query in request.parameters.name.locations and returns request.parameters.name.values[index], where [index] is the value for query in locations. Parameter values are not URL decoded.
$statusCode() message.status.code Status code
$storageType([arg]) variable.body

You can specify any variable in the API context. When no variable is specified, the default variable message.body is used.

Storage type of the message. The supported values are binary, empty, graphql, json, stream, or xml.
$urlParameter('name')
  • request.parameters.name.locations

    The supported keywords are path and query

  • request.parameters.name.values
Searches for the index of path and query in request.parameters.name.locations and returns a single array that contains both path and query values from request.parameters.name.values. When the URL contains both path and query parameter values, the array includes the path values first followed by the query values. The values of each parameter type are added in the order that they are received. Parameter values are URL decoded.
For example, the following URL contains both path and query parameter values.
http://example.com/petstore/cats/adopt?breed=Sphynx&breed=Siamese
The $urlParameter('breed') URL returns the following array of values.
[cats, adopt, Sphynx, Siamese]

In this example, the URL includes an API path that is configured as /petstore/{breed}/{breed}, where breed is configured to be a path parameter of the API path. As a result, cats and adopt are included in the output.

$xpath(path, xpathExpression) You can specify any writable variable in the API context. The xpathExpression must be a literal string. Allows use of XPath expressions. The following example specifies all price elements in the source.
$xpath($, '//price')

Table 2 lists the functional extensions that you can use with GraphQL APIs.

Table 2. Functional extensions to JSONata for GraphQL
Extension Variable Description
$gqlActiveOperation([graphql_message]) message.body Gets the active operation found in the specified GraphQL message. The operationName must be the same as the name of the active operation.
$gqlAlias(graphql_field_node) message.body Gets the alias of a GraphQL field node.
$gqlFragments([graphql_message]) message.body Gets the fragments found in the specified GraphQL message.
$gqlName([graphql_node]) message.body Gets the node name. For operations, the node name is the operationName. For fields, fragment definitions, arguments, and other elements, the node name is the name of the element. By default, the operationName of message.body is retrieved.
$gqlOperations([graphql_message]) message.body Gets the operations found in the specified GraphQL message.
$gqlType([graphql_node]) message.body The operation type of the active operation is retrieved for Query, Mutation, and Subscription query types.
In addition to the functional extensions, you can use the following operators:
  • You can use the & (concatenation) navigation operator.

You can use the following JSONata numeric operators:

  • + (addition)
  • - (subtraction)
  • * (multiplication)
  • / (division)
  • % (modulo)

You can use the following JSONata comparison operators for number values or strings:

  • =
  • !=
  • <
  • >
  • <=
  • >=
You can also use the following operators and expressions.
  • Parentheses to convert a sequence into an array, specify operator precedence, or compute complex expressions on a context value.
  • Array ranges and predicate expressions.
  • Single asterisk (*) and double asterisk (**) wildcard characters.
The following elements of a GraphQL query can be exposed in JSONata notation using the syntax shown.
  • query

    The entire GraphQL query including operations and fragments.

  • operationName

    For an anonymous operation, operationName can be empty.

  • ~fragmentSpreadName
  • on~typeCondition
  • ~~fragmentDefinitionName

Simple condition statements

The following examples show conditions that use a single function.

This example uses the $httpVerb() extension to specify the HTTP method of the request.
$httpVerb()="GET"
This example uses the $operationPath() extension to specify the path of the operation.
$operationPath()="/base/path-2"
This example uses the $operationID() extension to specify the operation ID.
$operationID()="test-gatewayscript-GET"
This example uses the $statusCode() extension to specify the message status code.
$statusCode()=200
This example uses the $header(name) extension to specify the content type of the message header.
$header("Content-Type")="application/json"

Combining conditions with logical operators

You can use and and or operators to combine multiple functions in a single condition.

This example specifies an HTTP GET request and an API operation path equal to test-gatewayscript-GET.
$httpVerb()="GET" and $operationPath()="test-gatewayscript-GET"
This example specifies either a POST or PUT request.
$httpVerb()="POST" or $httpVerb()="PUT"
This example specifies an API operation ID equal to test-gatewayscript_POST and a message status code equal to 200, or an API operation ID equal to test-gatewayscript-GET and a message status code equal to 500.
($operationID()="test-gatewayscript-POST" and $statusCode()=200) or ($operationID()="test-gatewayscript-GET" and $statusCode()=500)
This example specifies an API operation ID equal to test-gatewayscript-POST and a message status code equal to 200 with an API operation path equal to /base/path-2.
($operationID()="test-gatewayscript-POST" and $statusCode()=200) and $operationPath()="/base/path-2"
This example specifies a message header content type equal to text/plain and a message header length equal to 300, or a message status code equal to 200.
($header("Content-Type")="text/plain" and $header("Content-Length")=300) or $statusCode()= 200

Example switch policy

- 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'