# Workflow Expressions

Workflow model parameters can use expressions to select/manipulate workflow and/or state data.

Note that different data filters play a big role as to which parts of the states data are to be used when the expression is evaluated. Reference the [State Data Filtering](https://docs.a4b.vn/xflow/workflow-data-handling#state-data-filters) section for more information about state data filters.

By default, all workflow expressions should be defined using the [jq](https://stedolan.github.io/jq/) [version 1.6](https://github.com/stedolan/jq/releases/tag/jq-1.6) syntax. You can find more information on jq in its [manual](https://stedolan.github.io/jq/manual/).

Serverless Workflow does not mandate the use of jq and it's possible to use an expression language of your choice with the restriction that a single one must be used for all expressions in a workflow definition. If a different expression language needs to be used, make sure to set the workflow `expressionLang` property to identify it to runtime implementations.

Note that using a non-default expression language could lower the portability of your workflow definitions across multiple container/cloud platforms.

All workflow expressions in this document, [specification examples](https://docs.a4b.vn/xflow/examples) as well as [comparisons examples](https://docs.a4b.vn/xflow/core-concepts/comparisons) are written using the default jq syntax.

Workflow expressions have the following format:

```bash
${ expression }
```

Where `expression` can be either an in-line expression, or a reference to a defined expression function definition.

To reference a defined expression function definition the expression must have the following format, for example:

```bash
${ fn:myExprFuncName }
```

Where `fn` is the namespace of the defined expression functions and `myExprName` is the unique expression function name.

To show some expression examples, let's say we have the following state data:

{% code lineNumbers="true" %}

```json
{
  "applicant": {
    "name": "John Doe",
    "age"      : 26,
    "email": "johndoe@something.com",
    "address"  : {
      "streetAddress": "Naist street",
      "city"         : "Nara",
      "postalCode"   : "630-0192"
    },
    "phoneNumbers": [
      {
        "type"  : "iPhone",
        "number": "0123-4567-8888"
      },
      {
        "type"  : "home",
        "number": "0123-4567-8910"
      }
    ]
  }
}
```

{% endcode %}

In our workflow model we can define our reusable expression function:

{% code lineNumbers="true" %}

```json
{
"functions": [
  {
    "name": "is-adult-applicant",
    "operation": ".applicant | .age > 18",
    "type": "expression"
  }
]
}
```

{% endcode %}

We will get back to this function definition in just a bit, but now let's take a look at using an inline expression that sets an input parameter inside an action for example:

{% code lineNumbers="true" %}

```json
{
"actions": [
    {
        "functionRef": {
            "refName": "confirm-applicant",
            "arguments": {
                "applicantName": "${ .applicant.name }"
            }
        }
    }
]
}
```

{% endcode %}

In this case our input parameter `applicantName` would be set to "John Doe".

Expressions can also be used to select and manipulate state data, this is in particularly useful for state data filters.

For example let's use another inline expression:

{% code lineNumbers="true" %}

```json
{
   "stateDataFilter": {
       "output": "${ .applicant | {applicant: .name, contactInfo: { email: .email, phone: .phoneNumbers }} }"
   }
}
```

{% endcode %}

This would set the data output of the particular state to:

{% code lineNumbers="true" %}

```json
{
  "applicant": "John Doe",
  "contactInfo": {
    "email": "johndoe@something.com",
    "phone": [
      {
        "type": "iPhone",
        "number": "0123-4567-8888"
      },
      {
        "type": "home",
        "number": "0123-4567-8910"
      }
    ]
  }
}
```

{% endcode %}

[Switch state](https://docs.a4b.vn/xflow/developer-guide/workflow-states-reference/switch-state) [conditions](https://github.com/serverlessworkflow/specification/blob/main/specification.md#Switch-State-Data-Conditions) require for expressions to be resolved to a boolean value (`true`/`false`).

We can now get back to our previously defined "IsAdultApplicant" expression function and reference it:

{% code lineNumbers="true" %}

```json
{
  "dataConditions": [ {
    "condition": "${ fn:is-adult-applicant }",
    "transition": "start-application"
  }]
}
```

{% endcode %}

As previously mentioned, expressions are evaluated against certain subsets of data. For example the `parameters` param of the [functionRef definition](https://github.com/serverlessworkflow/specification/blob/main/specification.md#FunctionRef-Definition) can evaluate expressions only against the data that is available to the [action](https://github.com/serverlessworkflow/specification/blob/main/specification.md#Action-Definition) it belongs to. One thing to note here are the top-level [workflow definition](https://github.com/serverlessworkflow/specification/blob/main/specification.md#Workflow-Definition-Structure) parameters. Expressions defined in them can only be evaluated against the initial [workflow data input](https://docs.a4b.vn/xflow/workflow-data-handling#workflow-data-input).

For example let's say that we have a workflow data input of:

{% code lineNumbers="true" %}

```json
{
   "inputVersion" : "1.0.0"
}
```

{% endcode %}

we can use this expression in the workflow "version" parameter:

{% code lineNumbers="true" %}

```json
{
   "name": "my-sample-workflow",
   "description": "Sample Workflow",
   "version": "${ .inputVersion }",
   "specVersion": "0.8"
}
```

{% endcode %}

which would set the workflow version to "1.0.0". Note that the workflow "name" property value is not allowed to use an expression. The workflow definition "name" must be a constant value.
