I have a use case where certain node must not be connected to other nodes.
Given a set of nodes types A, B, C
node A can only send its output to node B
node B can only send its output to node C
node C can only send its output to node A
Examples of valid flows
A -> B -> C
B -> C -> A
C -> A -> B
A -> B
B -> C
C -> A
Examples of Invalid Flows
B -> A -> B
C-> B
Feature Specs
- The client-side of a node must have a new property that will instruct the editor to not let it be connected to types that are not listed. This property can receive function that resolves to a boolean, or an array of node types. When using a function, the destination node properties are available to the context of this function, and
this
refers to the node that the user is pushing the wire from. When the resolved value is true, the connection is allowed. For example:
RED.nodes.registerType("my-type", {
category: "foo",
inputs: 1,
outputs: 1,
connectsTo: function(destination) {
// NOTE: destination has information about the node that I'm about to connect to
// NOTE: "this" is also available and it refers to the node's own context
return destination.type === "foo"
},
...
})
or
RED.nodes.registerType("my-type", {
category: "foo",
inputs: 1,
outputs: 1,
connectsTo: ["my-type-2"],
...
})
-
connectsTo
is an opt-in feature. This means that nothing that is currently working will stop working. -
Developer is responsible for declaring all nodes, such as
debug
, when using this feature. If he fails to do it, consumers won't be able to attach a debug node to the output of the origin node, unless they disable the "Connection Checks" for that node type, as described below. -
This feature can be disabled per node type in the Editor. This way consumers can also opt-in when combining these nodes with their custom nodes. To disable this feature, users can "Double Click" on any node in the canvas of that particular type, and uncheck a prop called "Disable Connection Checks".
-
When the User drags the wire to a node that is not allowed to receive a connection from the origin node, the editor will display an "x" where the connection would have happened as a means to show the User that the connection isn't allowed. Additionally, while dragging a wire, similarly as the "catch" node, only the nodes that can receive a connection from another node must be highlighted to minimize the number of tries.
-
Additionaly, in the server, when the flow is about to be started, a validation will run to verify all
connectsTo
that are enabled (remember, the User can disable connectsTo for a particular type in the editor). If an error is found, the editor is notified, and the flow won't be started. All erros messages are sent to the editor as follows
The following error(s) were found:
- Node (id/name) of type A is not allowed to connect to Node (id/name) of type C
- Node (id/name) of type B is not allowed to connect to Node (id/name) of type A
- All node types that had its
connectsTo
disabled in the editor have to be serialized and available in the exportedflows.json
.
Another Reason for this feature
Type checking messages using JSON Schemas, or even Typescript, isn't enough to validate a node can process a certain message because 2 distinct node types can ouput messages with the same Schema/Type, but with different contextual data that won't be understanded by the node that is going to process the message. For example, the following messages from Node types A and B have the same schema:
output from A
{
"source" : "bar"
}
output from B
{
"source" : "#0103213913"
}
Both schemas are the same, but Node C can only process the output of B, based on the context of the data.
Use Case
I'm using Node-RED flows to describe flows using AWS resources, like SQS, SNS, Lambda, S3, EventBridge Triggers. Because the SQS can't send messages to my SNS node, I must not allow Users to do such connection in the Editor.
Valid flow
http-in -> SNS -> SQS -> Lambda -> S3 -> function -> http-out
Invalid flow
http-in -> SQS -> SNS -> Lambda -> S3 -> function -> http-out
I don't need this feature to make this work, but with it I would be able to provide a better UX for developers.