Http_in URL from environment variable

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

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

[{"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

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

image

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.

1 Like

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

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.

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.

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

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.

@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

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.

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.

[{"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

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