PR for JSON schema based editor - discussion

Hi folks,

Based on another discussion, I'm trying to rework the Node-RED JSON editor: only allow user input that is defined in the JSON schema. The purpose is to avoid that node developers have to implement large complex user interfaces, and instead only have to specify a JSON schema.

For example I need to build an Onvif device manager, to make my Onvif nodes more user friendly. Instead of building/maintining such a manager in Node-RED (which is rather undoable in my free time), I want use Nick's JSON editor and change it so a JSON schema can be applied. Indeed the Onvif consortium already offers a onvif.xsd file (which I can convert to a JSON schema file), that contains all the logic about Onvif camera configuration.

In this discussion I would like to get feedback about the issues I'm dealing with. Otherwise I'm making assumptions, and end up with a solution that won't be approved anyway.

Question 1 - Where/when specify the item name

My example schema:

{
   "$schema": "http://json-schema.org/draft-07/schema#",
   "$id": "http://example.com/product.schema.json",
   "title": "Product",
   "description": "A product from my web shop",
   "type": "object",
   "properties": {
      "productId": {
         "description": "The unique identifier for a product",
         "type": "integer"
      },
       "productName": {
         "description": "Name of the product",
         "type": "string"
      },
      "price": {
      "description": "The price of the product",
         "type": "number",
         "exclusiveMinimum": 0
      },
      "required": [ "productId", "productName" ]
}

This schema tells the editor that a product needs to have 3 items: "productId", "productName", and "price".

When you add a new item in the editor, I currently select automatically the first item from the schema (that hasn't been used yet). And when you click on an item name, you get a popup with all available items, to change the item afterwards:

json_schema_add_item

I did it like that because that is close to how it works without a JSON schema. However it isn't user friendly:

  1. There might be a lot of possible items in the JSON schema, so it is a bit ridiculous that I pick one (which you need to change afterwards).

  2. I would like to avoid that you can change the item name (via the dropdown box) afterwards. Indeed then I also have to remove all the children, because they won't belong to the new item name anymore. I.e. the new item whill have other constraints in the schema. In that case you should remove the item and add a new one.

So the question is how I know which item you want to add, when you click the "Add item" button:

  • Should Iwork with sub-menu items (after the "Add item" menu), but don't know if Node-RED supports that. And not sure if it is user friendly.

    image

  • Should I show a popup with a dropdown, where you need to select an item before you can add it.

  • Should I leave the item name empty (or an "Unknown" label), and that you have to click on it to show a dropdown box:

    image

*My personal choice is the last one, since that matches closest the current behaviour of the JSON editor (without the dropdown). Only disadvantage is that I cannot force the user to specify the item immediately. Although perhaps that is not a problem...

BTW in all 3 cases you can make a selection only once. As soon as you have specified an item, all (required) subitems should be added automatically and become unremovable.

Have a nice sunday,
Bart

3 Likes

Based on intuition the last option sounds like the best option to me also from the ones you suggested.

Damn, this option might be a problem.

I would like to hide (or disable) the "Add item" menu automatically in some circumstances:

image

  • When it is an array and the maximum number of array items has been added already:
    {
      "type": "array",
      "maxItems": 3
    }
    
  • When it is an object and all the allowed object properties have been added already.

However when I add an "Unknow-" item to the json (every time the "Add item" menu has been clicked), then I don't know which object properties have been added already. So I don't know whether I have to hide/disable the "Add item" menu...

Issue 2 - circular references

Seems that circular references are allowed in a JSON schema. For example an author can have a co-author, which is again an author and so on ...

{
  "author": {
    "properties": {
        "name": {
          "type": "string"
        },
        "co-author": {
            "$ref": "#/author" // circular reference
          }
        }
    }
  }
};

I saw that some of the available JSON libraries deal with this by using a proxy object, which does lazy loading.

However I wanted to add required fields automatically to the json: e.g. in the my first example schema above, there were two required items "productId" and "productName". It would be annoying if the user needs to add all those required fields manually, and get validation errors when he forgets to do that. Would be much more user friendly if all required items are being added automatically. However when I add such items automatically, I also need to add their required children also automatically and so on ...

But since circular references are allowed, I could end up in a infinite loop.
Does anybody have a tip how I can avoid this, and still avoid the user having to add everything by hand?

  • Should I add them only automatically at the first level only (i.e. not the entire subtree), and only when you expand the next level then required child items are added automatically. This way we also have some kind of lazy loading. But of course then the entire tree won't be builded automatically, when you don't expand all levels manually...
  • Should I add an extra new menu item "Add required items", so the user needs to specify explicit that he wants to add the required fields (instead of automatically adding required items)?
  • ...

If discarding the initial empty field and prefill with the first unused field (like in your first example) solves part of this issue, I'd suggest just go with that now. You can always try to improve it later when you'll have all the required parts solved in some way.

I would believe the beef of this change would be to have validation to schema and not small details like that anyway.

Considering your implementing this mainly for the ONVIF nodes in mind, does the ONVIF schema have circular references? If not, just document it as a limitation?

Thanks for reading until here :wink:
That would indeed be a solution. And perhaps add that extra button "Add required items" which is only showed/enabled when there are required items missing.

Hmm I don't know that for sure. Didn't have a detailed look yet, since I need to be able to implement this feature request before I can use it anyway.
BTW I have some other nodes in mind that could use this, like the unfinished Plotly node from @Paul-Reed and me. Because it has a very complex UI, that could perhaps become VERY simple via this feature request (combined with the Plotly schema). Anyway that is another story, and I don't want to go off-topic!

1 Like

Seems to make sense more and more... When I select automatically the first non-used object property (and show it in the json editor), then you will need to be able to change it afterwards. Which means I cannot make it readonly. But when you change it afterwards:

  • The children should be removed (because they don't match the new parent anymore, since those have other constraints in the schema). Perhaps I should add a "Tip" box at the bottom of the edit panel, to warn the user that this will happen (otherwise he might loose his data changes without knowing it)??
  • In the dropdown, I should only show the object properties which have not been used yet.

I belive there's a lot of corner cases in attempting to implement validation against a schema. My advise would be to start simple and develop further given your time constraints.

I can also kind of see you want to make your best effort on all the things you contribute. This is true for me also but on my side it's meant I rarely get anything done as I just don't like to push out code I'm not happy with and don't have time to make it so.

So I understand the mentality but at some points it could be healthy to also do some estimates how much users the nodes will be expected to have etc. :slightly_smiling_face:

1 Like