Dynamic routing with CEL interpolation and the forward-internal action

We’ve extended CEL interpolation support to the url field on the forward-internal action, enhancing dynamic routing. With this new capability, you can route requests to different internal endpoints based on the incoming request attributes—such as URL, host, path, query string, and headers—or other available variables during the request lifecycle.

The example below demonstrates how you can dynamically route traffic to internal endpoints based on the incoming subdomain of your request:

on_http_request:
  - name: redirect to an internal endpoint based on subdomain
    actions:
      - type: forward-internal
        config:
          # redirect from https://*.example.org to  https://<subdomain>.internal
          url: https://${req.host.split('.example.org)[0]}.internal
          binding: internal


This Traffic Policy rule uses CEL interpolation in the url field to extract the subdomain from the req.host variable on requests sent to an endpoint with the wildcard domain *.example.org. This allows you to easily redirect requests, such as blog.example.org, to distinct internal endpoints like blog.internal.

What can you do with CEL interpolation on the url configuration field?

Let’s look at some practical examples.

Dynamic traffic routing to customer networks

Many customers use ngrok for site-to-site connectivity into their customer networks—without the complexity of VPNs or requesting customers to open up ports on their firewall. These setups often involve assigning unique subdomains to each client. However, managing hundreds of customer-specific endpoints can quickly become complex and cumbersome. With CEL interpolation in the url configuration field, you can simplify these workflows and dynamically route requests based on request attributes.  

Let’s say you need to connect your SaaS application to customer networks. You can set up internal endpoints for each customer—for example, <CUSTOMER_1>.<YOUR_DOMAIN>.internal—and a public facing endpoint at <YOUR_APP>.<YOUR_DOMAIN>.com. You can route traffic based on a custom header, such as X-Customer-Value. Depending on its value, requests are forwarded to the appropriate internal endpoint. 

on_http_request:
  - name: redirect based on header value
    actions:
      - type: "forward-internal"
        config:
          url: https://${getReqHeader(‘X-Customer-Value’)[0]}.internal
          binding: internal

Dynamic traffic routing traffic to developer machines

For organizations with many developers using ngrok, CEL interpolation provides a powerful way to dynamically route traffic to individual developer environments. Services running on developer machines can be hosted on internal endpoints, while a public-facing endpoint serves as the entry point for requests. 

For example, you could set up internal endpoints for each developer—such as <DEV_1>.<YOUR_DOMAIN>.internal—and maintain a public facing endpoint at <YOUR_APP>.<YOUR_DOMAIN>.com. By routing traffic based on a custom header, such as X-Developer-ID, requests are dynamically forwarded to the appropriate internal endpoint. 

on_http_request:
  - name: redirect based on header value
    actions:
      - type: "forward-internal"
        config:
          url: https://${getReqHeader(‘X-Developer-ID’)[0]}.internal
          binding: internal

Create your first dynamic routes with CEL

You can learn more about how CEL interpolation works in our documentation, including an all-new hub for Traffic Policy references and examples.

Dynamic routing using CEL interpolation in the URL config field opens up powerful possibilities for managing complex traffic flows. We’d love to hear how you’re using CEL interpolation in your Traffic Policies! Share your use cases, creative solutions, or questions with us in our community repo or during our next session of Office Hours—we’re excited to see what you build.

API gateway
Traffic Policy
Gateways
Features
Production