Skip to content

Latest commit

 

History

History
231 lines (192 loc) · 5.42 KB

variables.md

File metadata and controls

231 lines (192 loc) · 5.42 KB

Variables

Variables can be used to store intermediate results during flow execution. A valid variable name starts with $ followed by a letter az or AZ or an underscore _. More letters, underscores, the numbers 09 or hyphens - may follow.

Predefined Variables

The following predefined variables exist:

  • $body: client request body
  • $env: environment variables
  • $request: client request information
  • $server: server information
  • $upstream: upstream response information
  • $error: Contains information regarding the most recent error, but is initially empty.

Try the following flow with

$ curl --data hello localhost:8080 | jq
<flow>
  <template>
  {
    "$request": {
      {{with $request }}{{: * }}{{end}}
    },
    "$body": {{ $body }},
    "$upstream": {{ $upstream }},
    "$server": {
      {{: $server/* }}
    },
    "$env": {
      {{: $env/* }}
    }
  }
  </template>
</flow>

The actions request and requests set the $upstream variable, too:

<flow>
  <requests>
  {
      "ok": {
      "url": "https://httpbin.org/status/200"
    },
    "failure": {
      "url": "https://httpbin.org/status/500"
    }
  }
  </requests>

  <template>
  {
    "$upstream": {
      {{with $upstream }}{{: * }}{{end}}
    }
  }
  </template>
</flow>
{
  "$upstream": {
    "ok": {
      "url": "https://httpbin.org/status/200",
      "status": 200,
      "headers": { … }
    },
    "failure": {
      …
    }
  }
}

Defining and Accessing Variables

Global variables are usually defined as the output of eval actions. The variable name is defined in the out="…" attribute. It must begin with $ followed by a letter and then more letters or numbers.

<flow>
  <!-- $x = 1 -->
  <eval out="$x">1</eval>
  <!-- $x = $x + 5 -->
  <eval in="$x" out="$x">{{ . + 5 }}</eval>
  <!-- $answer = $x * 7 -->
  <eval out="$answer">{{ $x * 7 }}</eval>
</flow>

For structured JSON variables, you can use the template action:

<flow>
  <template out="$cfg">
  {
    "stage": "prod",
    "mock": {{ boolean($request/get/mock) }},
    "answer": {{ $answer }}
  }
  </template>
</flow>

Variables may be copied with eval, too:

<flow>
  <eval out="$client_request">$request</eval>
  …
</flow>

Local Variables

Templates may define local variables with {{$… := …}}. Those variables are undefined outside the template they're defined in:

<flow>
  <template>{{$answer:= 42 }}</template>
  <!-- null -->
  <template>{{ $answer }}</template>
</flow>

📎 If a variable containing binary content is processed in a template or xslt action, its content will probably end up being truncated, garbled or both.

Undefined Variables

Attempting to access a variable that has not been set previously will yield an empty node-set. The empty node-set will be evaluated to false in conditions and produces the string null in placeholders:

<flow>
  <template>
    {{if $undefined }}
      will never be reached
    {{else}}
      <!-- null -->
      {{ $undefined }}
    {{end}}
  </template>
</flow>

$request

The $request variable contains information about the incoming client request, such as the URL, the request header fields and possibly the query component or cookies, if any were sent.

Example:

<request>
  <method>POST</method>
  <purpose>main</purpose>
  <debug/>
  <host>localhost</host>
  <port>12345</port>
  <id>XeeSVJ5AFt8VyXYagp3lvgAAACc</id>
  <url>http://localhost:12345/api/proxy?a=b&amp;c=d</url>
  <path>/api/proxy</path>
  <query>a=b&amp;c=d</query>
  <headers>
    <host>localhost:12345</host>
    <user-agent>curl/7.64.0</user-agent>
    <accept>*/*</accept>
    <cookie>NAME1=VALUE1; NAME2=VALUE2</cookie>
    <content-type>application/x-www-form-urlencoded</content-type>
    <foo>asdf</foo>
    <bar>qwer</bar>
    <content-length>17</content-length>
  </headers>
  <get>
    <a>b</a>
    <c>d</c>
  </get>
  <cookies>
    <NAME1>VALUE1</NAME1>
    <NAME2>VALUE2</NAME2>
  </cookies>
</request>

As HTTP request headers are defined to be case-insensitive, their names are lower-cased for convenient access even if the client has sent the field name with upper-case letters, e.g.:

$request/headers/user-agent

$error

Both client request and response, as well as upstream request and response validation errors will store information about the error in $error. While initially empty, $error will have the following properties containing information about the most recent error:

  • status - the HTTP status that is used by default for responses if the error was passed to the client (type: number)
  • code - an error code (type: number)
  • message - a single line of text describing the error (type: string)
  • info - detailed information about the error (type: array of string)
  • requestID - the requestID as it should appear in the logs (type: string)

Example:

{
  "status": 400,
  "code": 3204,
  "message": "Input Validation Failed",
  "info": [
    "Path /api/empty-body/ not found."
  ],
  "requestID": "XYOGvOu@c2mhpIlgFB-yPwAAAF8"
}

See also