json-schema-org / json-schema-spec

The JSON Schema specification
http://json-schema.org/
Other
3.7k stars 260 forks source link

[Proposal] JSON UI Schema: define UI behaviours for all current elements #252

Closed Anthropic closed 7 years ago

Anthropic commented 7 years ago

Issue

I always feel uneasy about *Of being assumed to be acting to define model properties not found in properties and I see other potential future options 'select'/'if' looking the same way. I feel it inhibits the ability to accurately generate a UI without needing to process validation or model keywords as if they are a ui-schema definition.

I have seen implementations provide a plus sign and then display part of the form that is in the oneOf list and I've seen all sorts of other combinations where implementations have tried to define what option to display in a drop down to choose a form fragment to display. I've seen discussion around special types of keys for referencing the *Of elements from a UI schema.

I don't believe we should create a blueprint and leave out important structural details and ask the builder to decide what to do.

Proposal

*Of

I'd like to see all properties defined in Of, or any other keyword that can bypass properties, be required in properties and relatively referenced instead if the user intends to have a form generator display the fields at all. In addition I would like to see a clear definition of how* any such item is to be processed to display so that implementations can provide a level of consistency, this is not specifically about the look, but instead the elemental level, at least, of what is provided (a select could be tabs or radio buttons for example).

Essentially something along the lines of: if the fields are in properties and there is a title value within all the oneOf's then make them selectable sub schema, otherwise, don't and use them only for validation instead.

Obviously to be refined, but I wanted to give an idea about the direction of what I am suggesting.

Keys

To be clear, I am not suggesting you MUST have everything in properties, if the schema is purely for validation"", you do not need to, however if you want the fields rendered at all**, then they should be.

For Model and UI purposes I believe it makes more sense for them to be required in properties as it makes it easier to reference them as keys internally by any implementation. I believe it is also required for clear UI schema definitions.

Definition

I would like to see any new proposals require a definition and discussion on how it should be rendered in the UI, both with, and importantly without, UI Schema. As part of UI schema I think it should define an option to just render the schema in the way json-schema-form has "*" and "..." key options that should render the fields based exclusively on their schema definition. As such the UI schema specification will need to define how all elements should be rendered both with and without additional information provided..

Feedback

I would like to hear perspectives on this for consideration. I know @awwright has expressed a desire to always know how the schema should render and @Relequestual @epoberezkin @handrews may have input on this too, but if anyone knows people related to implementations please tag them in.

relative of: #67

epoberezkin commented 7 years ago

@Anthropic to summarise: Problem - it is impossible in general case to generate UI from a given JSON schema Solution - to restrict JSON schema (or to define required restrictions) in such a way that it is always possible to generate UI from it

Is it what you are saying?

Anthropic commented 7 years ago

@epoberezkin close, not restricted in that anything is required, no change to validation ideally. Just definition that tells users in the spec if you don't have this attribute then what you add won't generate in a form as there's not enough information, so clarification for each element within the spec to explain the UI required elements and what that would produce in a non prescriptive way where possible.

Is that clearer at all?

epoberezkin commented 7 years ago

@Anthropic so then the problem you want solved is the ambiguity in how UI should be generated from JSON schema, and the proposed solution is to define additional specification and/or keywords to make UI generation deterministic. Is that right?

Anthropic commented 7 years ago

Yes, that's the essence of it, the other parts are all related to that so that's the most important element.

handrews commented 7 years ago

Lots of good stuff here, @Anthropic! Overall, I think that JSON UI Schema should include a section clarifying how it interacts with any validation keywords that could be ambiguous or problematic- see PR #251 for hyper-schema where I exclude any hyper-schema keywords under a "not" (at any level of depth, no matter the validation outcome) or from non-validating or otherwise irrelevant subschemas of "oneOf", "anyOf", or "dependencies". I also clarify how to use hyper-schema keywords with "contains", which requires a bit more specification than merely using "contains" for validation.

I see other potential future options 'select'/'if' looking the same way

I think "if" in particular could be leveraged to express UI field interactions- display the fields from the "if" and depending on the contents entered, either display the "then" or "else" fields. This could handle quite a few interactions without necessarily needing to define new keywords for UI.


I need to think through your proposals a bit more before responding further. In general, the validation spec should make sense without (and be unconstrained by) hyper-schema, UI schema, etc. UI schema, hyper-schema, etc. should specify their own constraints and exclusions on validation as needed.

epoberezkin commented 7 years ago

In general, the validation spec should make sense without (and be unconstrained by) hyper-schema, UI schema, etc. UI schema, hyper-schema, etc. should specify their own constraints and exclusions on validation as needed.

@handrews I agree

epoberezkin commented 7 years ago

@Anthropic I think there is a bigger problem with using JSON schema for UI generation, and it consists of two parts: 1) it is impossible in general case to generate "form UI" from any given JSON schema 2) it is impossible in general case to describe any given "form UI" using JSON schema (that is also used to validate the data in the form).

@awwright would probably say that there are two sets - the set of JSON schemas and the set of "form UIs". Only a subset of JSON schemas can be converted to "form UI" (with or without additional definition file). Only subset of "form UIs" can be expressed using JSON schema.

The problem you are describing (ambiguity) is a part of problem 1 stated above.

I can elaborate or illustrate with some examples, I was raising these problems in #67.

epoberezkin commented 7 years ago

@Anthropic @handrews A bigger question for me is that I do not understand the motivation to standardise the format of JSON file used for "form UI" definition. Standardisation is a substantial effort on its own, as we all can see from JSON schema and hyper-schema, that goes far beyond just understanding what the standard should or could look like. So unless we clearly understand the motivation behind such standardisation, the problems we want to solve and the criteria we need to meet, there will never be enough effort from community to create and publish such standard. The fact that we have a lot of conversation about UI schema and no real progress I see as a confirmation that the motivation is unclear and the goals are not set.

Don't get me wrong here please. I totally like the idea of using JSON format as a schema to generate "form UI", and there are many ways to do it (in combination with JSON schema as @Anthropic is doing or separately like some other libraries do, when JSON schema is only used for validation, but not for defining UI - that's the approach that @handrews seem to prefer and I like it more as well). I am only questioning the need for a standard here as opposed to multiple library-specific file formats (that can use JSON schema to define such formats).

In general, such standards are usually needed to provide interoperability between different systems, particularly when they use different languages. When we are talking about data transfer/storage we need a standard to define the schema for such data, and JSON schema addresses this need. What kind of interoperability problem we would solve by standardising "form UI" definition schema?

The common ground that already exists for UI applications is web standards (HTML/CSS/JavaScript), and these standards are adopted in desktop, mobile and embedded platforms, so we don't really have multi-language problem here. Neither we have multi-system problem - different platforms usually need differently looking UIs for the same app. And if we want to generate UI for non-web platforms (e.g. desktop, native mobile apps), we usually have to follow very different UI conventions and these platforms already have their own very advanced ways to define UIs.

What I think is long due is a standard for UI to supersede HTML/CSS, as using them to define application UI (not just "form UI") seems like the most unnatural part of web application development to me. But I don't think it should be JSON based. And it is completely out of scope of this discussion.

I would really like to understand the motivation why do we need a JSON-based standard for "form UI" and not just libraries that solve that problem.

handrews commented 7 years ago

@epoberezkin There are many JavaScript frameworks and/or JS+HTML+CSS component systems. A JSON-based form description system allows implementations in multiple frameworks or component systems to produce the same UI. This is of tremendous benefit when a codebase inevitably drops an older framework for a newer one (in JS development, this seems to be necessary every two to four years depending on how much you want to deal with bleeding edge vs outdated/unsupported systems).

JSON Schema Form is already dealing with this in that it started as an Angular project, has a semi-independent React incarnation, and is trying to construct a framework-neutral core. But even with a core that multiple of today's frameworks can use, a large enough paradigm shift in UI development will require a new implementation.

Additionally, I see UI Schema as describing interactions independent of HTML/CSS vs mobile native vs (unlikely as it may be to occur) desktop native UIs. Not all concepts will translate equally well, but the ability to work from a common specification to provide the best implementation of the form in the given type of UI is a big win.

In short, I see a lot of reasons for a JSON UI schema. The effort involved in the standardization is irrelevant to whether it is needed- JSON UI schema does not block any of the JSON Schema standards already underway. This is why I assert that validation must not be aware of, much less dependent upon, UI schema.

The fact that we have "no real progress" means that we just started and most of us are trying to get Draft 06 of the main specifications published. I've personally been avoiding starting large new discussions, so it's not like there's been effort to get conversations started that have failed- we just haven't had time to focus on it yet. However, there is a great deal of enthusiasm for the project among my co-workers and we will hopefully be able to participate more in the near future.

epoberezkin commented 7 years ago

@handrews I agree that there is a need to define UI / interactions in framework/library agnostic way. I still see two problems though:

handrews commented 7 years ago

@epoberezkin if you don't support a JSON UI solution, just don't participate in it. Feel free to start an XML-based project elsewhere (I'm not touching XML for this, personally). If you want to help shape the direction of a JSON-based system, that's a welcome discussion (although perhaps you should file your own issue rather than dragging @Anthropic's off in different directions). But if you just don't think it's a good idea in general, ignore it- no one will force you to implement it any more than you will be forced to implement hyper-schema, which you don't seem to find useful either.

epoberezkin commented 7 years ago

@handrews I am expressing concerns I have and I am interested to know how you think they should be addressed or why you think they should not be addressed. What I want is to:

I am not saying that JSON-based form UI definition is not needed, I am just looking for "shared justifications" of it being JSON-based, rather than using it as a default choice. Considering alternatives is the only way we can answer the questions above and justify our design choices.

Exactly because I am interested I am raising all these questions as we seem to have skipped them all and jumped to implementation details straight away.

hyper-schema, which you don't seem to find useful either.

Where this is coming from? :) Never said it's not useful.

awwright commented 7 years ago

@epoberezkin Would an existing implementation not need to be deterministic? Maybe it would be inconsistent between implementations, but I don't really see a problem if the output is always valid.

epoberezkin commented 7 years ago

Sorry, I don't understand the question, you lost me here completely... Which implementation?

awwright commented 7 years ago

GitHub submitted my comment too soon... @epoberezkin a UI form generator

@Anthropic I'd like to see some use cases and examples... Also consider that JSON Schema has to function in a wide variety of applications and the design of the form might change depending on the application or device it's being rendered on.

if you want the fields rendered at all, then they should be.

Should be, or must be?

epoberezkin commented 7 years ago

@handrews @awwright I see. I think we should start from the goals, then define the spec based on these goals, then create implementations. That's how JSON schema was evolving more or less.

Before we have any specification, why we should be concerned with any library-specific problems? And building specification because we have an implementation feels a bit wrong. Even if we skip the discussion of whether JSON is the right language, we still need to consider the fundamental differences between UI structure and data structure and consider different existing approaches in existing implementations (i.e. 1) start from JSON schema for UI definition and enrich it or 2) start from completely different format and link it to JSON schema) before deciding which approach should be standardised.

Lack of determinism is specific only to approach 1), by the way, so maybe it's not the problem of the implementation but the problem of approach.

handrews commented 7 years ago

@epoberezkin this is a proposal to start from JSON Schema, using JSON. If you want to propose something else, do that somewhere else. A non-JSON or non-JSON Schema-based system has nothing to do with this project or repository and should not be discussed here.

epoberezkin commented 7 years ago

@handrews I think you are trying to push me away without making an effort to understand what I am talking about, which is a bit strange... UI schema can be JSON-schema based, but it can be based on JSON schema in different ways.

Approach 1: use JSON schema that is used to validate data model and enrich it with additional keywords and use such enriched schema to generate UI. The problem with this approach that it very much limits what UI can be generated. There are several implementations and they all have this non-determinism issues. Approach 2: use JSON schema to define the format of the form definition. Also use JSON schema to validate form fields, form sections and form data as a whole. There are implementations that follow this approach more or less, and they don't have non-determinism problems.

Why should we standardise approach 1 and not approach 2? Why approach two is out of scope of this discussion? It is also JSON and JSON-schema based. To provide you a simple example of the second approach, the form definition could look like:

{
  "schema": {
    "$id": "user",
    "properties": {
      "first_name": {},
      "family_name": {}
    }
  },
  "uiItems": [
    {
      "uiType": "group",
      "uiLabel": "User",
      "uiItems": [
        {
          "uiType": "input-text",
          "uiLabel": "First name",
          "schema": { "$ref": "user#/properties/first_name" },
          "dataPath": "/first_name"
        },
        {
          "uiType": "input-text",
          "uiLabel": "Family name",
          "schema": { "$ref": "user#/properties/family_name" },
          "dataPath": "/family_name"
        }
      ]
    }
  ]
}

Don't focus on particular keywords here, they are not important. Please note that this approach allows to define UI structures that are different from data structures, while with approach 1 it is difficult. It also doesn't suffer from non-determinism problem because instead of implying required fields from JSON schema of the data model, you explicitly define these fields, their location in UI tree and ordering - none of these things is easy with UI definition implied in the JSON schema of data model.

You wrote above:

In general, the validation spec should make sense without (and be unconstrained by) hyper-schema, UI schema, etc. UI schema, hyper-schema, etc. should specify their own constraints and exclusions on validation as needed.

This is very easy to achieve with approach 2, and not easy at all with approach 1.

handrews commented 7 years ago

Why approach two is out of scope of this discussion?

It is not a JSON Schema vocabulary. There's nothing wrong with the idea of a JSON-based system that makes use of but does not extend JSON Schema, but that's not in scope for the JSON Schema organization. We are here to define JSON Schema as a media type and define standard JSON Schema vocabularies. We're not here to build other things that use JSON Schema.

That doesn't mean that approach two is worse than approach one, much less inherently bad, but there are endless ways to use JSON Schema and we need to not expand the JSON Schema organization to cover them. Our job is big enough with the media type and vocabularies.

I have so far considered JSON UI Schema as a vocabulary. That doesn't mean that it needs to be one, but if it isn't then it belongs elsewhere.

epoberezkin commented 7 years ago

These are all valid points. So, to answer my own question about goal/requirements/scope: the goal is to define a specification for a vocabulary that is used alongside validation vocabulary inside a JSON schema for the data model to allow deterministic generation of a basic form UI that can be used to enter all possible valid values for such data model.

Is that about right? @handrews @awwright @Anthropic ?

For me, it feels like it's a bit too restrictive and it would be quite difficult to cover such common UI requirements as field groups, tabs, etc.

Would using JSON schema + UI vocabulary to define a view model (= data structure that has the same tree structure as the view) rather than JSON schema for the data model be out of scope as well? And having vocabulary to link view model to data model?

epoberezkin commented 7 years ago

An example for the view model from the above UI definition could be:

{
  "user": {
    "first_name": "John",
    "last_name": "Doe"
  }
}

It doesn't have field ordering, but it can be in the UI schema as a UI-vocabulary keyword. But it has the same tree structure as the view, so in the schema for the view model you would have a place to have additional keywords to describe the visual appearance of the group ("user" level only exist in UI in this example, data model is flat).

If you start from the JSON schema for data model, all these UI structures either will be unsupported or will have to be defined separately and it will very quickly devolve into a separate, non-JSON-schema based UI definition format (most likely similar to my example in the previous comment).

epoberezkin commented 7 years ago

It is not a JSON Schema vocabulary

@handrews By the way, if you modify my first example as:

{
  "$schema": "http://json-schema.org/schema/draft-08",
  "$vocabulary": ["ui"],
  "$id": "user",
  "type": "object",
  "properties": {
    "first_name": {},
    "family_name": {}
  },
  "uiItems": [
    {
      "uiType": "group",
      "uiLabel": "User",
      "uiItems": [
        {
          "uiType": "input-text",
          "uiLabel": "First name",
          "schema": { "$ref": "user#/properties/first_name" },
          "dataPath": "/first_name"
        },
        {
          "uiType": "input-text",
          "uiLabel": "Family name",
          "schema": { "$ref": "user#/properties/family_name" },
          "dataPath": "/family_name"
        }
      ]
    }
  ]
}

would uiItems become a UI vocabulary keyword? Or is it too complex? That's what I mean above by saying "it will very quickly devolve into a separate, non-JSON-schema based UI definition format"

epoberezkin commented 7 years ago

And if you start from JSON schema for a view model, it could look like:

{
  "$schema": "http://json-schema.org/ui-schema",
  "$vocabulary": ["ui"],
  "$id": "user-view",
  "uiType": "form",
  "type": "object",
  "properties": {
    "user": {
      "uiType": "group",
      "uiLabel": "User",
      "type": "object",
      "uiOrder": ["first_name", "last_name"],
      "properties": {
        "first_name": {
          "$ref": "user-model#/properties/first_name",
          "uiType": "input-text",
          "uiLabel": "First name",
          "dataModel": "/first_name"
        },
        "last_name": {
          "$ref": "user-model#/properties/last_name",
          "uiType": "input-text",
          "uiLabel": "Last name",
          "dataModel": "/last_name"
        }
      }
    }
  }
}

I'm purposefully ignoring here that $ref should be the only keyword, additional vocabularies kind of add the motivation to allow to mix it with other keywords...

It complies with the requirement that @Anthropic proposes that all UI elements should be defined in properties, but the big difference here that instead of having JSON schema validation+UI vocabulary + independent UI definition file (that's the approach they use) it has only JSON schema validation+UI vocabulary but JSON schema defines view model rather than data model and it also defines links to data model that allow to create a bidirectional transformation between view and data models.

@handrews @awwright @Anthropic what do you think?

Ok. I rest my case. A lot to think about.

Anthropic commented 7 years ago

Go to sleep for a few hours and have to read a novel when I get up! Where to start...

@epoberezkin the motivation stems from finding several new projects that started up with near identical formats to ours and the obvious need to standardise for interoperability as any investment by business in a design pattern should not be a lock in proposition or expensive transition in my view if it can be avoided through collaboration. Each of the similar implementations I have been in discussions with are all willing to work toward a standard, should one exist.

I do not see the JSON Schema UI as being form based only, quite the opposite, I don't see that as a constraint, our framework can do the entire UI as it is essentially a component register with a schema to determine position and configuration. I like separation of model and view definition, a common requirement in my work is to be able to apply multiple different views to the same data set, however when I say separation, I do not mean that as not within the same schema document necessarily, I mean a view definition capable of being selected to apply to the data, which is why the values can't be interspersed with the data schema.

I envision a property of say 'ui' as part of the definition could encapsulate the ui specific definition dictionary and allow the same to be applied either within a data schema or separate at the document root, or even in a separate document, a processing first step by any implementation could make a canonical schema with a consistent structure either way.

It's incorrect to assume I want the ui schema to be within the same document, I have no desire to enforce a view of it being within the same document, I believe that should be entirely optional. Being language agnostic is a goal, there are already efforts to generate Java UI from schema, Android and others.

@awwright I was just feeling non-commital, MUST is probably the correct word to have used, I just ran out of time to confirm there were absolutely no exceptions. I have mocked up some illustrative structures (not valid schema obviously) below to give you some idea of ways I can see this working.

Note: Please don't get bogged down in the use of properties policies and actions in below examples, they are just to illustrate that I see other levels of information that are UI related that could be segmented into the ui property.

Very basic example
{
  "type": "object",
  "properties": {
    "field1": {
      "type": "string"
    },
    "field2": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "fieldA": {
          }
          "fieldB": {
          }
        }
      }
    }
  },
  "ui": {
    "view": {
      "title": "Administration",
      "items": [
        "*"
      ]
    },
    "policies": {
      "policyA": {}
      "policyB": {}
    },
    "actions": {
    }
  }
}
Slightly more complex example
{
  "type": "object",
  "properties": {
    "field1": {
      "type": "string"
    },
    "field2": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "fieldA": {
          }
          "fieldB": {
          }
        }
      }
    }
  },
  "ui": {
    "view": {
      "admin": {
        "title": "Administration",
        "items": [
          "properties/field1",
          {
            "key":"properties/field2",
            "component": "tabs",
            "items": [
              "properties/field2/items/properties/fieldA"
            ]
          }
        ]
        "policies": {
          "policyA": false
        },
        "actions": {
        }
      }
      "cm": {
        "title": "Configuration Manager",
        "items": [
          {
            "key":"properties/field2",
            "component": "tabs",
            "items": [
              "properties/field2/items/properties/fieldA"
            ]
          }
        ]
        "policies": {
          "policyC": {}
        },
        "actions": {
        }
      }
    }
    "policies": {
      "policyA": {}
      "policyB": {}
    },
    "actions": {
    }
  }
}


That's all I have time now to try to explain, I will do my best to review tomorrow's comment flood a bit quicker ;)

epoberezkin commented 7 years ago

@Anthropic essentially you are leaning towards an independent format similar to what I was describing, but for some reason you are using JSON schema as part of UI definition, rather than just a validation concern.

Interesting what @handrews will say, but I think this amount of data inside ui keyword seems very much stretching what a vocabulary should be.

I honestly think that your approach is worse than completely independent format using JSON schema, a thing that @handrews believes is out of scope of this organisation.

On the other hand, the last approach that I suggested, when you use schema for view model, rather than for data model, with UI keywords "interspersed" in schema seems to be fitting "JSON schema vocabulary". An additional consideration in this approach is that it requires defining an additional concept - a view model, and how any given UI could/should be mapped into a data structure. It's not difficult, we've done it in milojs framework...

I am not sure which of two is better, I would probably prefer a completely independent UI definition format, using rather than based on JSON schema, a hybrid approach seems to be combining disadvantages of both approaches...

handrews commented 7 years ago

I'm closing this in favor of json-schema-org/json-schema-vocabularies#2 (anything not covered there should be opened as a new issue in that repo). Most of this issue is just an argument that is acknowledged and given context in the vocabulary issue anyway.