---
name: azion-run-a-function-on-one-path-and-roll-it-back
description: >-
  Run a function instance on one path and one method with a Run Function rule, and roll the path back by turning the rule off.
---

# Run a function on one path, and roll it back

You run a function on one path and one method of an application with a *Run Function* rule, and roll the path back by turning that rule off, from Azion Console, the API, or the Azion CLI. To create the function and its instance first, refer to [Functions quickstart](/en/documentation/platform/functions/quickstart/).

A rule for one path moves that path to the function, while every other path keeps the rule that served it before. The rule's **Active** switch, the `active` field in the API, is the rollback: a rule turned off does not run, and the path goes back to the earlier rule with no change to any other rule.

```mermaid
%%{init: {"layout": "dagre", "themeVariables": {"fontSize": "13px"}, "flowchart": {"nodeSpacing": 12, "rankSpacing": 12, "padding": 6, "wrappingWidth": 70, "minNodeWidth": 40, "useMaxWidth": true}}}%%
flowchart TD
  Req["A request reaches the application"] --> R1["Rule 1: every path, Set Connector"]
  R1 --> R2{"Rule 2, if active: is it GET /api/items?"}
  R2 -->|"yes"| Fn["Run Function: the instance answers"]
  R2 -->|"no, or the rule is off"| Origin["The origin answers through the connector"]
```

1. Every request matches the first rule, which sends it to the origin through a connector.
2. A `GET` request for `/api/items` also matches the second rule while it is active, and the function instance answers it.
3. Any other request, and every request once the second rule is off, is answered by the origin.

---

## Prerequisites

### Console

- An application served by a workload, with a rule that sends every request to a connector. To create them, refer to [Applications quickstart](/en/documentation/platform/applications/quickstart/).
- Application Accelerator on the application, which the *Run Function* behavior requires. To turn it on, refer to [Turn on Application Accelerator](/en/documentation/guides/application-performance/cache-and-purge/cache-settings/#turn-on-application-accelerator).
- A function instance on the application. To create the function and the instance, refer to [Functions quickstart](/en/documentation/platform/functions/quickstart/), which creates both.

### CLI

- An application served by a workload, with a rule that sends every request to a connector. To create them, refer to [Applications quickstart](/en/documentation/platform/applications/quickstart/).
- Application Accelerator on the application, which the *Run Function* behavior requires. To turn it on, refer to [Turn on Application Accelerator](/en/documentation/guides/application-performance/cache-and-purge/cache-settings/#turn-on-application-accelerator).
- A function instance on the application. To create the function and the instance, refer to [Functions quickstart](/en/documentation/platform/functions/quickstart/), which creates both.
- The [Azion CLI](/en/documentation/devtools/cli/) installed and authorized.

### API

- An application served by a workload, with a rule that sends every request to a connector. To create them, refer to [Applications quickstart](/en/documentation/platform/applications/quickstart/).
- Application Accelerator on the application, which the *Run Function* behavior requires. To turn it on, refer to [Turn on Application Accelerator](/en/documentation/guides/application-performance/cache-and-purge/cache-settings/#turn-on-application-accelerator).
- A function instance on the application. To create the function and the instance, refer to [Functions quickstart](/en/documentation/platform/functions/quickstart/), which creates both.
- A [personal token](/en/documentation/guides/platform/account-and-billing/personal-tokens/).

The examples run the instance `<function-instance-id>` on `GET /api/items` of the application `<application-id>`, on the domain `www.example.com`. Replace them with your values.

---

## Create the rule for the path and the method

The rule carries two criteria groups, one for the path and one for the method. Groups join with `and`, so a request matches only when both match, and a `POST` to the same path keeps reaching the origin. Neither `${uri}` nor `${request_method}` needs a Product on the application.

A new rule is created at the end of the Request Phase, after the rule that sends every path to the connector. A rule placed after one that ends the processing, such as *Deliver* or *Finish Request Phase*, never runs for the requests that rule matches.

### Console

To create the rule in Azion Console:

1. **Go to the Rules Engine tab**

   Access [Azion Console](https://console.azion.com/) > **Applications** > **your application**, then go to the **Rules Engine** tab.

2. **Select + Rule**

3. **Name the rule**

   Enter a name that identifies the path. For example: `function - GET /api/items`.

4. **Select Request Phase**

5. **Match the path**

   In the **Criteria** section, set the criterion to `${uri}` *is equal* `/api/items`.

6. **Match the method**

   Add a second criteria group with one criterion: `${request_method}` *is equal* `GET`.

7. **In the Behaviors section, select Run Function**

8. **Select the function instance**

9. **Select Save**

The rule appears in the **Request** list, after the rule that sends every path to the connector.

### CLI

The CLI reads the rule from a JSON file. To create the rule:

1. **Write the rule to a file**

   Save the following as `rule.json`, with the ID of the function instance in `attributes.value`:

   ```json
   {
     "name": "function - GET /api/items",
     "active": true,
     "criteria": [
       [
         { "variable": "${uri}", "conditional": "if", "operator": "is_equal", "argument": "/api/items" }
       ],
       [
         { "variable": "${request_method}", "conditional": "if", "operator": "is_equal", "argument": "GET" }
       ]
     ],
     "behaviors": [{ "type": "run_function", "attributes": { "value": <function-instance-id> } }]
   }
   ```

2. **Create the rule**

   ```bash
   azion create rules-engine --application-id <application-id> --phase request --file rule.json
   ```

   The command prints the ID of the rule:

   ```text
   Created Rules Engine with ID <rule-id>
   ```

Keep the rule ID for the rollback.

### API

The criteria carry `${uri}`, which a shell expands, so the body is sent from a file. To create the rule:

1. **Write the rule to a file**

   Save the following as `rule.json`, with the ID of the function instance in `attributes.value`:

   ```json
   {
     "name": "function - GET /api/items",
     "active": true,
     "criteria": [
       [
         { "variable": "${uri}", "conditional": "if", "operator": "is_equal", "argument": "/api/items" }
       ],
       [
         { "variable": "${request_method}", "conditional": "if", "operator": "is_equal", "argument": "GET" }
       ]
     ],
     "behaviors": [{ "type": "run_function", "attributes": { "value": <function-instance-id> } }]
   }
   ```

2. **Send the create request**

   ```bash
   curl --request POST \
     --url https://api.azion.com/v4/workspace/applications/<application-id>/request_rules \
     --header 'Accept: application/json' \
     --header 'Authorization: Token <personal-token>' \
     --header 'Content-Type: application/json' \
     --data @rule.json
   ```

The API answers `202` with `"state": "pending"` and the rule as it was stored, with its `id` and the `order` it holds in the phase. Keep the `id` for the rollback.

`GET /api/items` runs the function instance, and every other request keeps reaching the origin. A new rule takes a few minutes to reach every data center. When *Run Function* is missing from the behaviors list, the application needs Application Accelerator.

In the [Modernize a monolithic application without a rewrite](/en/documentation/use-cases/build-and-run-applications/modernize-a-monolithic-application-without-a-rewrite/) use case, this section takes these values:

| Setting       | Value                                                                                                          |
| ------------- | -------------------------------------------------------------------------------------------------------------- |
| **Rule name** | `strangler - GET /api/stores`                                                                                  |
| **Criteria**  | one group with `${uri}` *is equal* `/api/stores`, and a second group with `${request_method}` *is equal* `GET` |
| **Behavior**  | *Run Function* with the `stores-route` instance, whose ID goes in `attributes.value` in the API                |

`GET /api/stores` is answered by the function, and every other request still reaches the monolith. A rule change takes a few minutes to reach every data center, so the cut-over and the rollback each spread over that time, and both versions of the route answer while they do.

In the [Build AI agents](/en/documentation/use-cases/build-and-run-ai-workloads/build-ai-agents/) use case, this section takes these values:

| Setting  | Value                                                                                            |
| -------- | ------------------------------------------------------------------------------------------------ |
| Rule     | `agent - tasks and approvals`, in the Request Phase                                              |
| Criteria | One group, `${uri}` *starts with* `/api/agent/`, in place of this guide's path and method groups |
| Behavior | **Run Function**, selecting the `ops-agent` instance                                             |

A task sent to `/api/agent/tasks` runs until the model answers, a refund needs approval, or six steps pass, and every start, pause, decision, and end lands in `task_events`. A new rule takes a few minutes to propagate.

---

## Roll the path back

Turning the rule off keeps its criteria and its behavior, so turning it on again moves the path back to the function. The update changes `active` alone.

### Console

To turn the rule off in Azion Console:

1. **Go to the Rules Engine tab**

   Access [Azion Console](https://console.azion.com/) > **Applications** > **your application**, then go to the **Rules Engine** tab.

2. **Select the rule**

   In the **Request** list, select `function - GET /api/items`.

3. **Turn off the Active switch**

   In the **Status** section, turn off **Active**.

4. **Select Save**

### CLI

The update is partial, so a file with `active` alone keeps the rest of the rule. To turn the rule off:

1. **Write the change to a file**

   Save the following as `rollback.json`:

   ```json
   { "active": false }
   ```

2. **Update the rule**

   ```bash
   azion update rules-engine --application-id <application-id> --rule-id <rule-id> --phase request --file rollback.json
   ```

   The command prints the ID of the rule:

   ```text
   Updated Rules Engine with ID <rule-id>
   ```

To move the path to the function again, run the same command with `{ "active": true }` in the file.

### API

To turn the rule off, send a `PATCH` request with `active` set to `false`. Replace `<rule-id>` with the `id` the create returned:

```bash
curl --request PATCH \
  --url https://api.azion.com/v4/workspace/applications/<application-id>/request_rules/<rule-id> \
  --header 'Accept: application/json' \
  --header 'Authorization: Token <personal-token>' \
  --header 'Content-Type: application/json' \
  --data '{ "active": false }'
```

The rule keeps its criteria and its behavior, with `active` set to `false`. To move the path to the function again, send the same request with `"active": true`.

`GET /api/items` reaches the origin again once the change propagates. While it propagates, some data centers still run the function, so both versions answer for a few minutes.

---

## Check which version answers

The **Upstream Addr** of a request record names who answered it, and `127.0.0.1:1666` marks Azion Runtime. To check the path in Real-Time Events:

1. **Open Real-Time Events**

   Access [Azion Console](https://console.azion.com/) > **Real-Time Events**.

2. **Select the HTTP Requests data source**

3. **Filter by the path**

   In **Filter by**, enter `request_uri like '/api/items%'`.

4. **Read the Upstream Addr of each record**

While the rule is active, the `GET` records carry `127.0.0.1:1666`. After the rollback, new records carry the address and the port of the origin. For the filter syntax, refer to [Filter events](/en/documentation/guides/platform/observability/add-filters-events/).

In the [Modernize a monolithic application without a rewrite](/en/documentation/use-cases/build-and-run-applications/modernize-a-monolithic-application-without-a-rewrite/) use case, expect:

- **Every other route still reaches the monolith.** In Real-Time Events, the *HTTP Requests* records that match `request_uri like '/api/stores%'` carry **Upstream Addr** `127.0.0.1:1666` on `GET`, which marks Azion Runtime. The records of any other path of the site carry the monolith's address, `<monolith-ip>`, with its port.
- **Writes still reach the monolith.** The record of a `POST` to `/api/stores` carries the monolith's address, because the cut-over rule matches only `GET`.
- **The rollback holds.** A few minutes after the rule is turned off, `/api/stores` answers from the monolith, and new records for the path carry `<monolith-ip>`.

---

## Next steps

- [How Functions works](/en/documentation/platform/functions/how-it-works.md): How a function, its instance, and the rule that runs it fit together on each request.
- [Rules Engine for Applications](/en/documentation/platform/applications/rules-engine.md#run-function): The Run Function behavior, the rule fields, and the API that updates a rule.
- [Azion CLI rules-engine](/en/documentation/devtools/cli/resources/rules-engine.md): Every flag of the commands that create, update, and order rules.
- [Modernize a monolithic application without a rewrite](/en/documentation/use-cases/build-and-run-applications/modernize-a-monolithic-application-without-a-rewrite.md): Move one route of a monolith at a time to a function, and roll each one back.
- [Build AI agents](/en/documentation/use-cases/build-and-run-ai-workloads/build-ai-agents.md): Run the agent function on its API path, with a rule you can switch off to roll it back.
