# HTTP-IN dynamic URL path

**URL:** <https://discourse.nodered.org/t/http-in-dynamic-url-path/98802>\
**Category:** General\
**Created:** [23 August 2025 11:12 UTC](https://discourse.nodered.org/t/http-in-dynamic-url-path/98802 "2025-08-23T11:12:08Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![mindbowser](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/mindbowser/32/102929_2.png) [@mindbowser](https://discourse.nodered.org/u/mindbowser)\
**Post date:** [23 August 2025 11:12 UTC](https://discourse.nodered.org/t/http-in-dynamic-url-path/98802/1 "2025-08-23T11:12:08Z")

</div>

We have need where we want to add dynamic unique IDs in the url, e.g. If user setup http-in node with url as /bulk-export then normally user need to hit BASE\_URL + “node-red-api/bulk-export” but we want to add extra params like BASE\_URL + “/integration-id/node-red-api/bulk-export”

How to achieve this?

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [23 August 2025 11:50 UTC](https://discourse.nodered.org/t/http-in-dynamic-url-path/98802/2 "2025-08-23T11:50:45Z")

</div>

You can use express endpoint patterns like `/my-endpoint/:param1` or even `/my-endpoint/*`

Pretty sure this is detailed in the built in help.

Example: [Handle url parameters in an HTTP endpoint : Node-RED](https://cookbook.nodered.org/http/handle-url-parameters)

---

<div class="post-metadata">

**Author:** ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)\
**Post date:** [23 August 2025 13:53 UTC](https://discourse.nodered.org/t/http-in-dynamic-url-path/98802/3 "2025-08-23T13:53:01Z")

</div>

Further to Steves suggestion, you can also make the path optional using ?  
e.g `/:param1/:param2?`

---

<div class="post-metadata">

**Author:** ![MayurajMB](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/mayurajmb/32/102902_2.png) [@MayurajMB](https://discourse.nodered.org/u/MayurajMB)\
**Post date:** [23 August 2025 14:44 UTC](https://discourse.nodered.org/t/http-in-dynamic-url-path/98802/4 "2025-08-23T14:44:05Z")

</div>

Hi, I’m from the same team. Thanks for the suggestion, using params makes sense. However, we want to have a dynamic base-url that is based on our context.

For example one can enter `/main` in the url field and at the time of deployment, we want http-in node to append the `integrationid` from the context to the baseurl.

In our current approach, we’re patching http-node at startup to take context from `functionGlobalContext` and using it in the `httpNode.get`. But this feels like an unreliable approach.

Also our nodered is running embedded in the express app and all the routes are passed through a middleware which provides the said context.

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [23 August 2025 14:49 UTC](https://discourse.nodered.org/t/http-in-dynamic-url-path/98802/5 "2025-08-23T14:49:20Z")

</div>

You can use a context variable and compare it in a switch node and return a 404 status in the http-response

```log
                          +-base==flow.my_base → do-stuff → http-response(200)
http-in /:base/* → switch-|
                          +-otherwise → http-response(404)

```

---

<div class="post-metadata">

**Author:** ![mindbowser](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/mindbowser/32/102929_2.png) [@mindbowser](https://discourse.nodered.org/u/mindbowser)\
**Post date:** [23 August 2025 17:13 UTC](https://discourse.nodered.org/t/http-in-dynamic-url-path/98802/6 "2025-08-23T17:13:54Z")

</div>

Thanks for the revert. Here are some more details -

We’ve built a multi-tenant Node-RED setup where:

- Each **integration** can have multiple **environments** (e.g., sandbox, production)
- Each integration+environment combo has its own Node-RED flow
- Flows and configs are stored in S3 under:

```auto
s3://bucket/flows/{integrationId}/{environment}/{flowName}.json
s3://bucket/flows/{integrationId}/{environment}/_config/settings.json
s3://bucket/flows/{integrationId}/{environment}/_config/credentials.json
s3://bucket/flows/{integrationId}/{environment}/_config/sessions.json

```

- We use a custom storage module that overrides getFlows, saveFlows, getCredentials, etc.
- Flow ID is structured as: {integrationId}{environment}{flowName}

* * *

### **How It’s Working Now**

#### **1. Patched HTTP-in Node**

We patched 21-httpin.js to auto-add integration context to routes:

```auto
function getUrlWithContext(url, RED) {
  const context = RED.settings.functionGlobalContext.getIntegrationContext();
  if (context?.integrationId && context?.environment) {
    return '/' + context.integrationId + '/' + context.environment + url;
  }
  return url;
}

```

So a user-defined /webhook gets translated to:

```auto
/{integrationId}/{environment}/webhook

```

#### **2. Flow Loading**

We load flows dynamically:

```auto
const context = { integrationId, environment, flowName };
await RED.nodes.setFlows(flows, context);

```

#### **3. Context Access**

- Flow context is set at runtime
- Function nodes use flow.get('integrationId'), etc.
- Global context exposes getIntegrationContext() method

* * *

### **Issues We’re Facing**

#### **1. Routes Disappear**

When a new flow is loaded, routes from the previous flow vanish. Only the most recently loaded flow’s routes are active.

#### **2. Single Active Flow Limitation**

Node-RED core assumes one active flow. setFlows() replaces all routes and state.

#### **3. Shared Runtime State**

Even though we isolate settings and credentials in S3, the Node-RED runtime (context, routes, memory) is still global.

* * *

### **Our Current Stack Involves**

- Patching core file 21-httpin.js
- Custom storage module for flows and credentials from S3
- Middleware for request URL rewriting
- Dynamically loading flows based on access
- Manually registering HTTP routes per flow

* * *

### **Open Points We’re Thinking About**

- Whether to continue with a single Node-RED instance for all tenants
- Or switch to per-tenant Node-RED instances
- How to maintain multiple active flows and their HTTP routes concurrently
- Ensuring route, credential, and context isolation
- Whether to preload all flows at startup and how to manage scale

* * *

### **Also Considered**

- Multiple Node-RED instances (resource-intensive)
- Projects feature (doesn’t solve HTTP routing issues)
- Custom nodes for flow context (loses native node behavior)

* * *

Happy to share more if helpful — posting this to see if others have taken a similar route or found a cleaner pattern.

 ![Screenshot 2025-08-23 at 10.05.35 PM](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/c/f/cf3757f7a2649dbb8d3484e0d965260ded3db2bb.png)

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [23 August 2025 19:48 UTC](https://discourse.nodered.org/t/http-in-dynamic-url-path/98802/7 "2025-08-23T19:48:31Z")

</div>

The usual way to handle this when using a microservice architecture like Node-RED is to have multiple service instances behind a proxy.

Anything less risks compromising individual customer's data.

---

<div class="post-metadata">

**Author:** ![mindbowser](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/mindbowser/32/102929_2.png) [@mindbowser](https://discourse.nodered.org/u/mindbowser)\
**Post date:** [24 August 2025 05:58 UTC](https://discourse.nodered.org/t/http-in-dynamic-url-path/98802/8 "2025-08-24T05:58:48Z")

</div>

Thanks.This does makes sense, so In this case if we deploy multiple Node Red instances per environment, still our issue around http-in route customization remains, so you meant add integration id using patch approach and using credentials middleware injection route internally to specific integration?

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [24 August 2025 11:46 UTC](https://discourse.nodered.org/t/http-in-dynamic-url-path/98802/9 "2025-08-24T11:46:20Z")

</div>

You can use the proxy to help route things, you don't just have to rely on Node-RED.

By having multiple instances, the node-red end of the url is greatly simplified. The proxy hides the gory details.

Too many people treat node-red as the complete answer when it doesn't need to be and often shouldn't be.

Using a proxy would also give you far better and stronger options for authentication.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [23 October 2025 11:46 UTC](https://discourse.nodered.org/t/http-in-dynamic-url-path/98802/10 "2025-10-23T11:46:56Z")

</div>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.
