# Http\_in URL from environment variable

**URL:** <https://discourse.nodered.org/t/http-in-url-from-environment-variable/79561>\
**Category:** General\
**Tags:** http-in\
**Created:** [3 July 2023 17:05 UTC](https://discourse.nodered.org/t/http-in-url-from-environment-variable/79561 "2023-07-03T17:05:23Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Barbudor](https://avatars.discourse-cdn.com/v4/letter/b/4af34b/32.png) [@Barbudor](https://discourse.nodered.org/u/Barbudor)\
**Post date:** [3 July 2023 17:05 UTC](https://discourse.nodered.org/t/http-in-url-from-environment-variable/79561/1 "2023-07-03T17:05:23Z")

</div>

Hello

I have a use case where it would be very convenient for me to be able to specify the URL of a http-in node from an environment variable.  
Actually I want to build a generic "webhook" subflow which would be made from

- A http\_in node
- A function node to verify the authentication from the provider

So to make it generic, my subflow would take 2 parameters/environment variables:

- the URL =\> goes into http\_in
- the key used for authentication =\> goes into my function node

I would appreciate some pointer to where I could find doc or examples

- How to modify the HTML so that the URL can be either a string or an environment variable
- How to identify in JS that I directly get the URL or an environment name

I tried to look at Switch and Change but as they are creating things dynamically that a bit next-level for me.  
What other node would you suggest me to look into ?

I would be happy to propose a PR is you are interrested

Thanks

---

<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:** [3 July 2023 17:44 UTC](https://discourse.nodered.org/t/http-in-url-from-environment-variable/79561/2 "2023-07-03T17:44:24Z")

</div>

I think you can do what you wish using named paramaters `:name`  
Have a look at this simple example subflow

```auto
[{"id":"9098bccb0d4722cb","type":"subflow","name":"Subflow 1","info":"","category":"","in":[],"out":[],"env":[{"name":"key","type":"str","value":"","ui":{"label":{"en-US":"Key"},"type":"input","opts":{"types":["str"]}}},{"name":"route","type":"str","value":"","ui":{"label":{"en-US":"Route"},"type":"input","opts":{"types":["str"]}}}],"meta":{},"color":"#DDAA99"},{"id":"60e32bc7d3ec53fd","type":"http in","z":"9098bccb0d4722cb","name":"","url":"/api/:route/:key","method":"get","upload":false,"swaggerDoc":"","x":170,"y":180,"wires":[["920d0459152cda6e","2c57686dfda2f11b"]]},{"id":"e1f5942d5fe31779","type":"http response","z":"9098bccb0d4722cb","name":"","statusCode":"","headers":{},"x":750,"y":180,"wires":[]},{"id":"db17d3f7c3f0bac7","type":"change","z":"9098bccb0d4722cb","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"access","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":160,"wires":[["e1f5942d5fe31779"]]},{"id":"920d0459152cda6e","type":"switch","z":"9098bccb0d4722cb","name":"","property":"req.params.route","propertyType":"msg","rules":[{"t":"eq","v":"route","vt":"env"},{"t":"else"}],"checkall":"false","repair":false,"outputs":2,"x":330,"y":180,"wires":[["e60d2c2be8eae39e"],["9cf1be7268a90c61"]]},{"id":"2c57686dfda2f11b","type":"debug","z":"9098bccb0d4722cb","name":"debug 316","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":410,"y":80,"wires":[]},{"id":"9cf1be7268a90c61","type":"change","z":"9098bccb0d4722cb","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"access denied","tot":"str"},{"t":"set","p":"statusCode","pt":"msg","to":"400","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":220,"wires":[["e1f5942d5fe31779"]]},{"id":"e60d2c2be8eae39e","type":"switch","z":"9098bccb0d4722cb","name":"","property":"req.params.key","propertyType":"msg","rules":[{"t":"eq","v":"key","vt":"env"},{"t":"else"}],"checkall":"false","repair":false,"outputs":2,"x":450,"y":180,"wires":[["db17d3f7c3f0bac7"],["9cf1be7268a90c61"]]},{"id":"54313e3128ebba28","type":"subflow:9098bccb0d4722cb","z":"b9860b4b9de8c8da","name":"","env":[{"name":"key","value":"my_key","type":"str"},{"name":"route","value":"route1","type":"str"}],"x":660,"y":4740,"wires":[]}]

```

you can enter the route and key in the subflow config.  
The access url for the subflow is `http://node-red_ip:1880/api/route1/my_key`

---

<div class="post-metadata">

**Author:** ![omrid](https://avatars.discourse-cdn.com/v4/letter/o/77aa72/32.png) [@omrid](https://discourse.nodered.org/u/omrid)\
**Post date:** [4 July 2023 09:12 UTC](https://discourse.nodered.org/t/http-in-url-from-environment-variable/79561/3 "2023-07-04T09:12:16Z")

</div>

Why not just take the URL directly from the env var in your HTTP\_in node? (or am I missing something)

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/2/3/23032c6f145d20a438fa00ee0faa911eb7e58081.png)

In addition, I would recommend not to use subflows (for various reasons). Ever since the "call link" node has been added to Node-red, it's better to use a reusable group.

---

<div class="post-metadata">

**Author:** ![Barbudor](https://avatars.discourse-cdn.com/v4/letter/b/4af34b/32.png) [@Barbudor](https://discourse.nodered.org/u/Barbudor)\
**Post date:** [4 July 2023 10:12 UTC](https://discourse.nodered.org/t/http-in-url-from-environment-variable/79561/4 "2023-07-04T10:12:01Z")

</div>

Hi @omrid  
Are you sure that this syntax is working ?  
I will test

Hi @E1cid  
Thanks for the suggestion but this is not how I want to proceed  
You have a single http\_in and then find out which exact route was called and distribute from there  
Because of constraint design, I want separated http\_in for each route  
In addition your suggestion requires the routes to follow the same structure

---

<div class="post-metadata">

**Author:** ![Barbudor](https://avatars.discourse-cdn.com/v4/letter/b/4af34b/32.png) [@Barbudor](https://discourse.nodered.org/u/Barbudor)\
**Post date:** [4 July 2023 10:39 UTC](https://discourse.nodered.org/t/http-in-url-from-environment-variable/79561/5 "2023-07-04T10:39:39Z")

</div>

> [@omrid](#):
>
> I would recommend not to use subflows (for various reasons). Ever since the "call link" node has been added to Node-red, it's better to use a reusable group.

I would appreciate if you elaborate on that. What are the problem with Subflows ?  
Especially in that case, a call-link cannot replace a Subflow with no inputs and only output, especially as the http\_in node cannot be configured from a message.

---

<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:** [4 July 2023 10:52 UTC](https://discourse.nodered.org/t/http-in-url-from-environment-variable/79561/6 "2023-07-04T10:52:38Z")

</div>

> [@Barbudor](#):
>
> Thanks for the suggestion but this is not how I want to proceed  
> You have a single http\_in and then find out which exact route was called and distribute from there  
> Because of constraint design, I want separated http\_in for each route  
> In addition your suggestion requires the routes to follow the same structure

Then what would be the purpose of the subflow, as you can set the url directly in the separate http in nodes.  
As to following same structure, not quite true as you can omit :route using a ?, would need more info about your constraint design to explain more.

The subflow does not distribute, you would add a subflow for each different url you wish to use, and configure in the subflow. The subflow would only pass on msg from the http in, if the route matches the subflow config.

---

<div class="post-metadata">

**Author:** ![omrid](https://avatars.discourse-cdn.com/v4/letter/o/77aa72/32.png) [@omrid](https://discourse.nodered.org/u/omrid)\
**Post date:** [4 July 2023 11:42 UTC](https://discourse.nodered.org/t/http-in-url-from-environment-variable/79561/7 "2023-07-04T11:42:14Z")

</div>

> [@Barbudor](#):
>
> > [@omrid](#):
> >
> > I would recommend not to use subflows (for various reasons). Ever since the "call link" node has been added to Node-red, it's better to use a reusable group.
> 
> I would appreciate if you elaborate on that. What are the problem with Subflows ?  
> Especially in that case, a call-link cannot replace a Subflow with no inputs and only output, especially as the http\_in node cannot be configured from a message.

The reasons I don't use subflows anymore, are:

1. Subflows work like macros. behind the scenes they replicate their included nodes. So if you have 10 instances of a subflow of 10 nodes, you would be instantiating 100 nodes. In big projects it will consume a lot of memory and increase the flow load time significantly.
2. Subflows maintain their own private (per-instance) flow context and environment variables, and this can confuse & complicate things, especially with subflows which are nested within subflows.
3. The functionality within subflows has some limitations

Having said that, in your case maybe using subflows would be the right approach, since it will allow you to localize the url env variable inside the subflow instance configuration.

Ah, and yes, **${...}** works with HTTP\_in

---

<div class="post-metadata">

**Author:** ![Barbudor](https://avatars.discourse-cdn.com/v4/letter/b/4af34b/32.png) [@Barbudor](https://discourse.nodered.org/u/Barbudor)\
**Post date:** [4 July 2023 12:10 UTC](https://discourse.nodered.org/t/http-in-url-from-environment-variable/79561/8 "2023-07-04T12:10:33Z")

</div>

Hi @E1cid  
Answering to your message about my use-case

> The subflow does not distribute, you would add a subflow for each different url you wish to use

This is exactly my purpose  
The reasons is we want each flows that process a webhook are independant and can be moved to an another instances easily without relaying on a "distribution flow" (one with 1 single http\_in and a big switch)  
We prefer letting NodeRed do that for us

> Then what would be the purpose of the subflow

The system we are using (SVIX) has 1 different signing key for each webhook  
So the idea is to have a subflow with 2 parameters (subflows env variable):

- The webhook URL to listen to
- The associated signing key  
Then in the subflow there would be 2 nodes:
- 1 http\_in that would get it's URL from the env variable
- 1 function node that does the signature verification

As of today I need to dupplicate this pair of nodes and configure each separately  
Having this in the form of a subflow with a single place to configure it would be more convenient.  
May be at some point I will code from scratch a SVIX webhook node that does that but I don't have the time for that currently.

I hope this is clear on my intention and reasons.

---

<div class="post-metadata">

**Author:** ![Barbudor](https://avatars.discourse-cdn.com/v4/letter/b/4af34b/32.png) [@Barbudor](https://discourse.nodered.org/u/Barbudor)\
**Post date:** [4 July 2023 12:15 UTC](https://discourse.nodered.org/t/http-in-url-from-environment-variable/79561/9 "2023-07-04T12:15:34Z")

</div>

@E1cid

Thanks also a lot for your comments about subflows  
I have noticed the confusion with their own flow context which cannot be exposed in the GUI. I agree it can makes problems a bit harder to follow.

Regarding memory usage, indeed may be we should check that more deeply. We already use call-link in some occasions for complex "sub flows".

But we really find subflows very nice to avoid coding straight nodes from scratch. Generally our subflows are simple (3-5 nodes) and used only to encapsule http API calls.

Thanks again

---

<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:** [4 July 2023 13:08 UTC](https://discourse.nodered.org/t/http-in-url-from-environment-variable/79561/10 "2023-07-04T13:08:22Z")

</div>

> [@Barbudor](#):
>
> ngle http\_in and a big switch)

The switch would only be 2 rules the env route and otherwise, no other rules would be require, agian the subflow does not distribute, it just checks that it is allowed to receive the incoming requests route, that is cofigured in that instant of the subflow.

> [@Barbudor](#):
>
> - The webhook URL to listen to
> - The associated signing key  
> Then in the subflow there would be 2 nodes:
> - 1 http\_in that would get it's URL from the env variable
> - 1 function node that does the signature verification

The url could be configured in the http in nodes and the key could be added in a change node via any input msg, env, context etc, no subflow required.

[edit]  
After testing seems the http in node does not like being in a subflow.  
you can do similar using link in out and dynamic link call.  
set route in link in nodes and key in change nodes  
e.g.

```auto
[{"id":"b4f299efe620de9f","type":"http in","z":"b9860b4b9de8c8da","name":"","url":"/api/:route/:key","method":"get","upload":false,"swaggerDoc":"","x":410,"y":4820,"wires":[["db09ab6ea62bd760"]]},{"id":"cee018508ce41309","type":"http response","z":"b9860b4b9de8c8da","name":"","statusCode":"","headers":{},"x":950,"y":4820,"wires":[]},{"id":"d3b82170b681e87a","type":"link out","z":"b9860b4b9de8c8da","name":"","mode":"return","links":[],"x":935,"y":4580,"wires":[]},{"id":"06a83eb19b8f1150","type":"link in","z":"b9860b4b9de8c8da","name":"route1","links":[],"x":385,"y":4580,"wires":[["2879f2d698c47007"]]},{"id":"38b7241428dd1f14","type":"link call","z":"b9860b4b9de8c8da","name":"","links":[],"linkType":"dynamic","timeout":"10","x":820,"y":4820,"wires":[["cee018508ce41309"]]},{"id":"db09ab6ea62bd760","type":"change","z":"b9860b4b9de8c8da","name":"","rules":[{"t":"set","p":"target","pt":"msg","to":"req.params.route","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":640,"y":4820,"wires":[["38b7241428dd1f14"]]},{"id":"44061ccfab6a67ec","type":"catch","z":"b9860b4b9de8c8da","name":"","scope":["38b7241428dd1f14"],"uncaught":false,"x":610,"y":4880,"wires":[["9cf1be7268a90c61"]]},{"id":"9cf1be7268a90c61","type":"change","z":"b9860b4b9de8c8da","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"access denied","tot":"str"},{"t":"set","p":"statusCode","pt":"msg","to":"400","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":780,"y":4880,"wires":[["cee018508ce41309"]]},{"id":"6d02f30c46a41d8e","type":"link in","z":"b9860b4b9de8c8da","name":"route2","links":[],"x":385,"y":4700,"wires":[["5644ae542161a909","75525892c68243f8"]]},{"id":"5644ae542161a909","type":"debug","z":"b9860b4b9de8c8da","name":"debug 317","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":470,"y":4760,"wires":[]},{"id":"920d0459152cda6e","type":"switch","z":"b9860b4b9de8c8da","name":"","property":"req.params.key","propertyType":"msg","rules":[{"t":"eq","v":"key","vt":"msg"},{"t":"else"}],"checkall":"false","repair":false,"outputs":2,"x":650,"y":4580,"wires":[["db17d3f7c3f0bac7"],["e42c491f21307897"]]},{"id":"db17d3f7c3f0bac7","type":"change","z":"b9860b4b9de8c8da","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"access","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":800,"y":4580,"wires":[["d3b82170b681e87a"]]},{"id":"1f4ee2a34ccbd15f","type":"switch","z":"b9860b4b9de8c8da","name":"","property":"req.params.key","propertyType":"msg","rules":[{"t":"eq","v":"key","vt":"msg"},{"t":"else"}],"checkall":"false","repair":false,"outputs":2,"x":650,"y":4700,"wires":[["ea41e4cbc13356cc"],["b250ca7dd3e949af"]]},{"id":"ea41e4cbc13356cc","type":"change","z":"b9860b4b9de8c8da","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"access","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":800,"y":4700,"wires":[["6bb41b29f8c0bb1e"]]},{"id":"2879f2d698c47007","type":"change","z":"b9860b4b9de8c8da","name":"","rules":[{"t":"set","p":"key","pt":"msg","to":"1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":510,"y":4580,"wires":[["920d0459152cda6e"]]},{"id":"75525892c68243f8","type":"change","z":"b9860b4b9de8c8da","name":"","rules":[{"t":"set","p":"key","pt":"msg","to":"1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":510,"y":4700,"wires":[["1f4ee2a34ccbd15f"]]},{"id":"6bb41b29f8c0bb1e","type":"link out","z":"b9860b4b9de8c8da","name":"","mode":"return","links":[],"x":935,"y":4700,"wires":[]},{"id":"b250ca7dd3e949af","type":"change","z":"b9860b4b9de8c8da","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"access denied","tot":"str"},{"t":"set","p":"statusCode","pt":"msg","to":"400","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":800,"y":4740,"wires":[["6bb41b29f8c0bb1e"]]},{"id":"e42c491f21307897","type":"change","z":"b9860b4b9de8c8da","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"access denied","tot":"str"},{"t":"set","p":"statusCode","pt":"msg","to":"400","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":800,"y":4620,"wires":[["d3b82170b681e87a"]]}]

```

`http://ip:1880/api/route1/1` or `http://ip:1880/api/route2/1`  
just add link in, change node for key, your api flow and link out back to link call

---

<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:** [2 September 2023 13:08 UTC](https://discourse.nodered.org/t/http-in-url-from-environment-variable/79561/11 "2023-09-02T13:08:51Z")

</div>

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