---
title: Configure routers and routes
description: The following sections provide an overview of how IG uses routers and routes to handle requests and their context. For information about creating routes in Studio, see the Studio guide.
component: pinggateway
version: 7.2
page_id: pinggateway:gateway-guide:routing
canonical_url: https://docs.pingidentity.com/pinggateway/7.2/gateway-guide/routing.html
revdate: 2022-04-25T11:07:10Z
section_ids:
  routing-router-setup: Configure routers
  routing-route-setup: Configure routes
  routing-inline: Configure objects inline or in the heap
  route-conditions: Set route conditions
  route-name-id-filename: Configure route names, IDs, and filenames
  routing-crest: Create and edit routes through Common REST
  routing-lockdown: Prevent the reload of routes
  routing-reserved: Access reserved routes
---

# Configure routers and routes

The following sections provide an overview of how IG uses routers and routes to handle requests and their context. For information about creating routes in Studio, see the [Studio guide](../studio-guide/preface.html#preface).

## Configure routers

The following `config.json` file configures a Router:

```json
{
  "handler": {
    "type": "Router",
    "name": "_router",
    "baseURI": "http://app.example.com:8081",
    "capture": "all"
  },
  "heap": [
    {
      "name": "JwtSession",
      "type": "JwtSession"
    },
    {
      "name": "capture",
      "type": "CaptureDecorator",
      "config": {
        "captureEntity": true,
        "_captureContext": true
      }
    }
  ]
}
```

In this configuration, all requests are passed with the default settings to the Router. The Router scans `$HOME/.openig/config/routes` at startup, and rescans the directory every 10 seconds. If routes have been added, deleted, or changed, the router applies the changes.

The main router and any subrouters are used to build the monitoring endpoints. For information about monitoring endpoints, see [Monitoring endpoints](../reference/Monitoring.html#monitoring-metrics). For information about the parameters of a router, see [Router](../reference/Handlers.html#Router).

## Configure routes

Routes are JSON configuration files that handle requests and their context, and then hand off any request they accept to a handler. Another way to think of a route is like an independent dispatch handler, as described in [DispatchHandler](../reference/Handlers.html#DispatchHandler).

Routes can have a base URI to change the scheme, host, and port of the request.

For information about the parameters of routes, see [Route](../reference/Handlers.html#Route).

### Configure objects inline or in the heap

If you use an object only once in the configuration, you can declare it inline in the route and do not need to name it. However, when you need use an object multiple times, declare it in the heap, and then reference it by name in the route.

The following route shows an inline declaration for a handler. The handler is a router to route requests to separate route configurations:

```json
{
  "handler": {
    "type": "Router"
  }
}
```

The following example shows a named router in the heap, and a handler references the router by its name:

```json
{
  "handler": "My Router",
  "heap": [
    {
      "name": "My Router",
      "type": "Router"
    }
  ]
}
```

Notice that the heap takes an array. Because the heap holds all configuration objects at the same level, you can impose any hierarchy or order when referencing objects. Note that when you declare all objects in the heap and reference them by name, neither hierarchy nor ordering are obvious from the structure of the configuration file alone.

### Set route conditions

When a route has a condition, it can handle only requests that meet the condition. When a route has no condition, it can handle any request.

A condition can be based on a characteristic of the request, context, or IG runtime environment, such as system properties or environment variables. Conditions are defined using IG expressions, as described in [Expressions](../reference/Expressions.html#Expressions).

Because routes define the conditions on which they accept a request, the router does not have to know about specific routes in advance. In other words, you can configure the router first and then add routes while IG is running.

The following example shows a route with no condition. This route accepts any request:

```json
{
  "name": "myroute",
  "handler": {
    "type": "ReverseProxyHandler"
  }
}
```

The following example shows the same route with a condition. This route accepts only requests whose path starts with `mycondition`:

```json
{
  "name": "myroute",
  "handler": {
    "type": "ReverseProxyHandler"
  },
  "condition": "${find(request.uri.path, '^/mycondition')}"
}
```

The following table lists some of the conditions used in routes in this guide:

**Example conditions and requests**

| Condition                                                                                       | Requests that meet the condition                                                                                                                                                                                                                                 |
| ----------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ```json
"${true}"
```                                                                           | All requests, because this expression always evaluates to `true`.                                                                                                                                                                                                |
| ```json
"${find(request.uri.path, '^/login')}"
```                                              | `http://app.example.com/login`, . . .                                                                                                                                                                                                                            |
| ```json
"${request.uri.host == 'api.example.com'}"
```                                          | `http://api.example.com/`, `https://api.example.com/home`, `http://api.example.com:8080/home`, . . .                                                                                                                                                             |
| ```json
"${find(contexts.client.remoteAddress, '127.0.0.1')}"
```                               | `http://localhost:8080/keygen`, `http://127.0.0.1:8080/keygen`, . . .Where `/keygen` is not mandatory and could be anything else.                                                                                                                                |
| ```json
"${find(request.uri.query, 'demo=simple')}"
```                                         | `http://ig.example.com:8080/login?demo=simple`, . . .For information about URI query, see `query` in [URI](../reference/RequestsResponsesContexts.html#URI).                                                                                                     |
| ```json
"${request.uri.scheme == 'http'}"
```                                                   | `http://ig.example.com:8080`, . . .                                                                                                                                                                                                                              |
| ```json
"${find(request.uri.path, '^/dispatch') or find(request.uri.path, '^/mylogin')}"
```    | `http://ig.example.com:8080/dispatch`, `http://ig.example.com:8080/mylogin`, . . .                                                                                                                                                                               |
| ```json
"${request.uri.host == 'sp1.example.com' and not find(request.uri.path, '^/saml')}"
``` | `http://sp1.example.com:8080/`, `http://sp1.example.com/mypath`, . . .Not `http://sp1.example.com:8080/saml`, `http://sp1.example.com/saml`, . . .                                                                                                               |
| ```json
"condition": "${find (request.uri.path, '&{uriPath}')}"
```                             | `http://ig.example.com:8080/hello`, when the following property is configured:```json
{
  "properties": {
    "uriPath": "hello"
  }
}
```For information about including properties in the configuration, see [Route properties](../reference/Properties.html). |
| ```json
"condition": "${request.headers['X-Forwarded-Host'][0] == 'service.example.com'}"
```   | Requests with the header `X-Forwarded-Host`, whose first value is `service.example.com`.                                                                                                                                                                         |

### Configure route names, IDs, and filenames

The filenames of routes have the extension `.json`, in lowercase.

The Router scans the routes folder for files with the `.json` extension, and uses the route's `name` property to order the routes in the configuration. If the route does not have a `name` property, the Router uses the route ID.

The route ID is managed as follows:

* When you add a route manually to the routes folder, the route ID is the value of the `_id` field. If there is no `_id` field, the route ID is the filename of the added route.

* When you add a route through the Common REST endpoint, the route ID is the value of the mandatory `_id` field.

* When you add a route through Studio, you can edit the default route ID.

|   |                                                                                                                     |
| - | ------------------------------------------------------------------------------------------------------------------- |
|   | The filename of a route cannot be `default.json`, and the route's `name` property and route ID cannot be `default`. |

## Create and edit routes through Common REST

|   |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| - | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | When IG is in production mode, you cannot manage, list, or even read routes through Common REST. For information about switching to development mode, see [Switching from production mode to development mode](../getting-started/next-steps.html#dev-mode-switch).If an AM policy agent is configured in the same container as IG, by default the policy agent intercepts requests to manage routes. When you try to add a route through Common REST, the policy agent redirects the request to AM and the route is not added.To override this behavior, add the URL pattern `/openig/api/*` to the list of not-enforced URI in the policy agent profile. Learn more in the Java Agent documentation or Web Agent documentation. |

Through Common REST, you can read, add, delete, and edit routes on IG without manually accessing the file system. You can also list the routes in the order that they are loaded in the configuration, and set fields to filter the information about the routes.

The following examples show some ways to manage routes through Common REST. For more information, see [About ForgeRock Common REST](../reference/preface.html#sec-about-crest).

Manage routes through common REST

Before you start, prepare IG as described in the [Getting started](../getting-started/preface.html).

1. Add the following route to IG:

   * Linux

   * Windows

   ```
   $HOME/.openig/config/routes/00-crest.json
   ```

   ```
   %appdata%\OpenIG\config\routes\00-crest.json
   ```

   ```json
   {
     "name": "crest",
     "handler": {
       "type": "StaticResponseHandler",
       "config": {
         "status": 200,
         "headers": {
           "Content-Type": [ "text/plain; charset=UTF-8" ]
         },
         "entity": "Hello world!"
       }
     },
     "condition": "${find(request.uri.path, '^/crest')}"
   }
   ```

   To check that the route is working, access the route on: <http://ig.example.com:8080/crest>.

2. To read a route through Common REST:

   1. Enter the following command in a terminal window:

      ```bash
      $ curl -v http://ig.example.com:8080/openig/api/system/objects/_router/routes/00-crest\?_prettyPrint\=true
      ```

      The route is displayed. Note that the route `_id` is displayed in the JSON of the route.

3. To add a route through Common REST:

   1. Move `$HOME/.openig/config/routes/00-crest.json` to `/tmp/00-crest .json`.

   2. Check in `$HOME/.openig/logs/route-system.log` that the route has been removed from the configuration, where `$HOME/.openig` is the instance directory. To double check, go to <http://ig.example.com:8080/crest>. You should get an HTTP 404 error.

   3. Enter the following command in a terminal window:

      ```bash
      $ curl -X PUT http://ig.example.com:8080/openig/api/system/objects/_router/routes/00-crest \
             -d "@/tmp/00-crest.json" \
             --header "Content-Type: application/json"
      ```

      This command posts the file in `/tmp/00-crest.json` to the `routes` directory.

   4. Check in `$HOME/.openig/logs/route-system.log` that the route has been added to configuration, where `$HOME/.openig` is the instance directory. To double-check, go to <http://ig.example.com:8080/crest>. You should see the "Hello world!" message.

4. To edit a route through Common REST:

   1. Edit `/tmp/00-crest.json` to change the message displayed by the response handler in the route.

   2. Enter the following command in a terminal window:

      ```bash
      $ curl -X PUT http://ig.example.com:8080/openig/api/system/objects/_router/routes/00-crest \
             -d "@/tmp/00-crest.json" \
             --header "Content-Type: application/json" \
             --header "If-Match: *"
      ```

      This command deploys the route with the new configuration. Because the changes are persisted into the configuration, the existing `$HOME/.openig/config/routes/00-crest.json` is replaced with the edited version in `/tmp/00-crest.json`.

   3. Check in `$HOME/.openig/logs/route-system.log` that the route has been updated, where `$HOME/.openig` is the instance directory. To double-check, go to <http://ig.example.com:8080/crest> to confirm that the displayed message has changed.

5. To delete a route through Common REST:

   1. Enter the following command in a terminal window:

      ```bash
      $ curl -X DELETE http://ig.example.com:8080/openig/api/system/objects/_router/routes/00-crest
      ```

   2. Check in `$HOME/.openig/logs/route-system.log` that the route has been removed from the configuration, where `$HOME/.openig` is the instance directory. To double-check, go to <http://ig.example.com:8080/crest>. You should get an HTTP 404 error.

6. To list the routes deployed on the router, in the order that they are tried by the router:

   1. Enter the following command in a terminal window:

      ```bash
      $ curl "http://ig.example.com:8080/openig/api/system/objects/_router/routes?_queryFilter=true"
      ```

      The list of loaded routes is displayed.

## Prevent the reload of routes

To prevent routes from being reloaded after startup, stop IG, edit the router `scanInterval`, and restart IG. When the interval is set to `disabled`, routes are loaded only at startup:

```json
{
  "name": "Router",
  "type": "Router",
  "config": {
    "scanInterval": "disabled"
  }
}
```

The following example changes the location where the router looks for the routes:

```json
{
  "name": "Router",
  "type": "Router",
  "config": {
    "directory": "/path/to/safe/routes",
    "scanInterval": "disabled"
  }
}
```

## Access reserved routes

IG uses an `ApiProtectionFilter` to protect the reserved routes. By default, the filter allows access to reserved routes only from the loopback address. To override this behavior, declare a custom `ApiProtectionFilter` in the top-level heap. For an example, see the CORS filter described in [Set up the UMA example](uma.html#uma-configuration).
