Skip to main content

Path-based Routing and Policy Decentralization with Cloud Endpoints

warning

Cloud endpoints are currently in private beta. The functionality listed below is not yet publicly available.

This guide provides an example on how to forward traffic to internal endpoints based on path using ngrok Cloud Endpoints. The cloud endpoint will have a traffic policy to route traffic to one of two internal endpoints depending on the path, but each internal endpoint will also have its own traffic policy to indepedently handle incoming traffic.

Core Concepts

  • Cloud endpoints are centrally managed endpoints in the cloud that can be used to route traffic to agent endpoints.
  • Internal endpoints are endpoints that are not publicly accessible and are only reachable from within your network by cloud endpoints via the forward action.
  • Path-Based Routing involves directing incoming traffic to different destinations based on the path component of a URL

Prerequisites

To follow this guide, you will need a local computer with ngrok installed by following our installation guides.

If you are going to be following along using ngrok CLI, you will need:

If you are going to be following along using CURL, you will need:

  • An ngrok API key as an environment variable named NGROK_API_KEY.

Step 1 — Create an Internal Endpoint for the Homepage

Let's start by creating a internal endpoint for the homepage endpoint, which will handle all non-API traffic.

ngrok http 80 \
--url https://homepage.internal

After running, you should see the endpoint with an "online" status at your domain. It will route traffic to the app running at your local port 80, which you can setup to have any HTTP server running.

Step 2 - Create an Internal Endpoint for the API

Next, let's create the another internal endpoint, this one for all traffic to the /api/ path.

We will use a traffic policy to simulate accessing an API endpoint.

---
on_http_request:
- expressions:
- "!(hasReqHeader('Api-Key'))"
actions:
- type: deny
config:
status_code: 404
- actions:
- type: custom-response
config:
status_code: 200
content: <html><body><h1>Hello world</h1><p>The quick brown fox jumps over the
lazy dog.</p></body></html>
headers:
content-type: text/html

The above traffic policy will deny all requests that do not have an API-Key header, and return a 200 status code with a custom response for all other requests.

Save the traffic policy as a file locally in your directory. Now, let's create an internal endpoint based on this traffic policy.

ngrok http 3001 \
--url https://api.internal \
--traffic-policy-file {PATH_TO_TRAFFIC_POLICY}

After running, you should see the endpoint with an "online" status for your endpoint.

Step 3 - Create a Domain for the Cloud Endpoint

Next, let's create the domain or TCP address that the cloud endpoint will reside on. For the purpose of this guide, we will create a ngrok HTTP domain.

ngrok api reserved-domains create \
--url ${NGROK_SUBDOMAIN}.ngrok.app
  • Replace NGROK_SUBDOMAIN with the subdomain you'd like to use for this guide.

After running, you should see the following:

200 OK
{
"id":"rd_2MT5Bqt0UzU0mFQ0zr8m1UQWCfm",
...
}

When you have completed this step, you can move on to the next step.

Step 4 — Create a Traffic Policy for your Cloud Endpoint

Now, we'll continue and create a traffic policy for the cloud endpoint. All incoming traffic will be preprocessed by this traffic policy, before being forwarded to the internal endpoints which may or may not have their own independent traffic policies. This separation allows for granularity and full control over how traffic is handled.

---
on_http_request:
- expressions:
- req.url.path.startsWith('/api/')
actions:
- type: forward-internal
config:
url: https://api.internal
binding: internal
- actions:
- type: forward-internal
config:
url: https://homepage.internal
binding: internal

Our traffic policy simply forwards traffic to one of our two internal endpoints based on the path. More complex traffic handling can be created at your discretion.

Step 5 — Create a ngrok Cloud Endpoint

Now we can create a ngrok Cloud Endpoint that points to our newly created internal endpoint. Cloud Endpoints can be created via the API or ngrok dashboard.

We use the URL from Step 2 as the url value in the traffic policy, and the traffic policy from Step 3 as the traffic-policy value. The binding is set to public so anyone can access our cloud endpoint.

Due to the shell's difficulty in parsing a more complex string that includes both ' and ", we will use Postman to send a POST request to the ngrok API instead of of using the ngrok api command.

  1. Open Postman and create a POST request to https://api.ngrok.com/endpoints.
  2. In the Authorization tab, select "API Key".
    • Set Key as Authorization
    • Set Value as Bearer NGROK_API_KEY
    • Set Add to as Header
  3. In the Headers tab, add a new header:
    • Create a header with the key Content-Type and value application/json
    • Create a header with the key Ngrok-Version and value 2
  4. In the Body tab, create a raw JSON:
{
"bindings": ["public"],
"description": "sample cloud endpoint",
"metadata": "{\"environment\": \"prod\"}",
"type": "cloud",
"traffic_policy": "{\"on_http_request\": [{\"expressions\": [\"req.url.path.startsWith('/api/')\"],\"actions\": [{\"type\": \"forward-internal\",\"config\": {\"url\": \"https://api.internal\",\"binding\": \"internal\"}}]},{\"actions\": [{\"type\": \"forward-internal\",\"config\": {\"url\": \"https://homepage.internal\",\"binding\": \"internal\"}}]}]}",
"url": "https://{NGROK_SUBDOMAIN}.ngrok.app"
}
  • Replace YOUR_NGROK_API_KEY with your ngrok API key.
  • Replace NGROK_SUBDOMAIN with the value used in Step 3.

For more details on using the API to create a cloud endpoint, see the API documentation for endpoints.

Conclusion

And we're done! You've successfully created a cloud endpoint that can be accessed from the URL you reserved: ${NGROK_SUBDOMAIN}.ngrok.app

On most paths, the cloud endpoint will refer to its traffic policy and forward traffic to our homepage internal endpoint, which exposes the app running on local port 80.

For /api/ paths, the cloud endpoint will forward traffic to our API internal endpoint. It requires an Api-Key header to access, and denies for all other requests. You won't be able to access the API normally from the browser, but you can use CURL or Postman to test it.

curl --header "Api-Key: AnythingHere" https://${NGROK_SUBDOMAIN}.ngrok.app/api/