3 Design: Flow file format v2
Nick O'Leary edited this page 2015-07-16 11:11:06 +01:00

Our current flow format is a flat list (array) of node objects. Everything is a node; a tab is a node, a node is a node, a subflow is a node.

When we added the 'tab' concept, it was a bit of a hack to the existing structure. 'tab' nodes define their properties, and then other nodes set their z property to be the id of the tab they are on.

When we added the 'subflow' concept, it was a bit more of a hack. 'subflow' nodes define their properties, and then other nodes that exist in the subflow set their z property to the id of the subflow they are in. Then, subflow instance nodes exist to place a subflow within an actual flow. They have a type of subflow:<id of subflow>.

I think it is fair to say, if we were to design a flow file format to implement the concepts we have today, we wouldn't have the flat list structure we do today.

Changing the flow file format is not a minor thing. It has big ramifications to backwards compatibility - the runtime and editor both need to cope with importing/loading "v1" flow file formats.

But making the change will make it much easier to add some new features moving forward, such as (in no particular order or reference to specific plans):

  • versioning to the flow objects
  • import/export of individual 'tabs'
  • new subflow capabilities
  • flow blocks/groups (similar to subflows, but not reusable palette entries)
  • additional meta-data (author, description, etc)
  • alternative format 'encoding' (yaml or json)

Some basic principles for the new format:

  • reflect the hierarchy of objects in the flow model
  • the 'tab' started as a visual organisation thing. But it started to have a behavioural element (catch nodes are scoped to the tab, for example). The new format renames 'tab' to 'flow'.
  • 'subflow' definitions are held at the top level. Instances of subflows can appear in any flow.
  • 'configuration nodes' are held at the top level. References to config nodes can appear in any flow.

Here's an example:

{
    "flows": [
        {
            "id": "123.456",
            "name": "name of the flow (aka tab)"
            "nodes": [
                { "id": "12345", "type":"function", "x":0, "y":0, ... },
                { "id": "67890", "type":"inject", "x":0, "y":0, ... }
            ]
        }
    ],
    "configs": [
        { "id": "12345", "type":"mqtt-broker", ... }
    ],
    "subflows": [
        {
            "id": "123.456",
            "name": "name of the subflow"
            "nodes": [
                { "id": "12345", "type":"function", "x":0, "y":0, ... },
                { "id": "67890", "type":"inject", "x":0, "y":0, ... }
            ]
        }
    ]
}

---
  flows: 
    - 
      id: "123.456"
      name: "name of the flow (aka tab)"
      nodes: 
        - 
          id: "12345"
          type: "function"
          x: 0
          y: 0
        - 
          id: "67890"
          type: "inject"
          x: 0
          y: 0
  configs: 
    - 
      id: "12345"
      type: "mqtt-broker"
  subflows: 
    - 
      id: "123.456"
      name: "name of the subflow"
      nodes: 
        - 
          id: "12345"
          type: "function"
          x: 0
          y: 0
        - 
          id: "67890"
          type: "inject"
          x: 0
          y: 0