Hi There,
Just out of interest, is there any work being done on definition of msg properties required/used by a function nodes?
What I'm thinking of is a specification of "possible" properties that are accessed on a msg object by a function defined in a function node.
I've been working on something like this for the client code node (i.e. code for the browser) using a tab in the editor panel:
What this tab defines are default values for properties on the msg object - so it plays a double act: defining those properties that the code expects and giving those properties a default value if these aren't set on the msg object.
This is something that might be useful for the function node where it can become non-obvious what "shape" (i.e. which properties) need to be defined on the msg object for the function node to work.
Having a "defaults" tab on the function node would allow defining those properties.
I guess this could be useful for highly visual folk. But it seems like a fair bit of work and complexity for minimal gain for people using function nodes for anything reasonably complex.
I always think that there are basically 2 reasons folk choose to use function nodes:
- To collapse down visual logic that has become visually distracting but is mostly stable.
- To provide some "business" logic that is hard to do with a collection of nodes.
I can see that some people would consider a way to define a function node's input message shape useful on occasion. Though given that function nodes are essentially textual in nature, I (personally) would have found a textual method of defining it more useful. I think there is already a node that allows you to check and enforce the shape of a message - can't remember the name - so not sure another node would be needed.
An extra tab in the function node itself that allows checking the input msgs and having an output choice of action/event might be more useful?
As for myself, if an input msg of some complexity is needed, I would either add a block comment with an example to the top of the function code or I would add a JSDoc block comment. Most of the time, I know what the upstream output looks like so it isn't often an issue. But occasionally, coming back to older logic, it can be helpful.
Plus it saves a node: no need for a change node to set default values for a function node that might - let's say - takes five property values on the msg object. Set them as defaults, copy & paste function node and have the same default behaviour without an extra change node (or setting values on a inject node).
It would bring the function node closer to a pre-configured in-built node, i.e., just as a debug node that debugs the complete message to the debug panel is a pre-configured debug node.
I find this particular useful if I'm spec'ing out a potential functionality of a future independent node. Replicate the functionality as a function node, play around with the scope of the functionality and then create a separate node package with exactly the same parameters as defined in the default tab.
I can sort of see it useful as pseudo-documentation - but there is no actual enforcement between this and the actual function code - you can still access whatever properties you want, so I'm not sure how much I would gain vs declaring properties defaults at the top of the function - at least then they are all in one chunk of code ( see various other discussions about separate editors/files for functions ) .
My feeling is that once I have reached for the function node - I am now writing code, and if I want docs I'll add them to the docs tab - I don't need yet a third place. But I can see that if you are wanting to enforce schemas or trying to create some tool to auto-convert functions to nodes then it could be useful.
I think there is a third option and that is creating code that is the documentation. I think folks don't think of writing code so that it becomes readable as documentation. That's what refactoring is all about: making code more understandable. (It was also the idea behind COBOL.)
My approach is generally that if I have the feeling that I need to write documentation, then I know my code is a mess and it should be refactored to become more understandable. The reason I do this is because code and documentation have the unfortunate habit of drifting apart - comments tend not to be updated. This then leads to confusion between code and documentation when reading the code. (But this unfortunate habit is largely fixed with AI.)
The only documentation I write is the high-level "what is the purpose" documentation but I avoid detailed documentation on individual code blocks - these should be understandable as code blocks. (This isn't an invitation to debate which amount of code is still understandable - this various across skill levels and does not have a fixed number of code lines - it's an gut feeling and experience thing.)
Of course, this is something that can happen down the road.
Even having highlight inside the editor when using a property that is isn't defined e.g. msg.notdefined would be red underlined in the editor until its defined in the tab. While msg.defined would be ok in the editor.
This doesn't mean it's an error or even warning, it's just a nice to have in the editor. I am not arguing this should become a "must do" or "error if not defined" feature.
It goes in the direction of typification of msg objects - i.e. if a msg has these three properties then it fulfils the type requirements for messages of this this type. (Just as a http-in message must have a .req property for the http-response node - this could be considered that the msg is of type "http request". Or rather, the http-response node takes a message object of type "http request" because it needs the req property.)