w3c / wot-thing-description

Web of Things (WoT) Thing Description
http://w3c.github.io/wot-thing-description/
Other
131 stars 63 forks source link

ThingModel extension via `tm:extends` of actions and events #2011

Open thjaeckle opened 2 months ago

thjaeckle commented 2 months ago

Hi WoT folks. 👋

I ran into a question regarding extension of ThingModels which I could not find answered in the 1.1 TD specification. How exactly are actions and events "extended"?

The specification states:

The Thing Model will inherit all definitions from the extended Thing Model

and:

A Thing Model SHOULD NOT overwrite the JSON names defined within the properties, actions, and/or events Map of the extended Thing Model. Definitions SHOULD NOT be overwritten in such a way that possible instance values are no longer valid compared to the origin extended definitions.

But for me it is not quite clear, if e.g. "input" not specified is "copied" to the extending model. Or if the "output" should be "merged" with the extended "output".

Or, if "input" and "output" explicitly must be copied to form a "valid TM action".

Example:

{
    "@context": ["https://www.w3.org/2022/wot/td/v1.1"], 
    "@type": "tm:ThingModel",
    "title": "Basic magic performing Thing Model",
    "actions": {
        "performMagic": {
            "input": {
               "title": "Magic number as input to the action",
               "type": "number"
            },
            "output": {
               "title": "Performed magic output",
               "type": "object",
               "properties": {
                   "result": {
                       "type": "string"
                   }
               },
               "required": [
                   "result"
               ]
            }
        }
    }
}

Example TM extending from the above:

{
    "@context": ["https://www.w3.org/2022/wot/td/v1.1"], 
    "@type": "tm:ThingModel",
    "title": "Black magic performing Thing Model",
    "links": [
      {
        "rel": "tm:extends",
        "href": "https://<.....>/basic-magic-performing-1.0.0.tm.jsonld",
        "type": "application/tm+json"
      }
    ],
    "actions": {
        "performMagic": {
            "output": {
               "title": "Performed black magic output",
               "type": "object",
               "properties": {
                   "blackMagicApplied": {
                       "type": "boolean"
                   }
               },
               "required": [
                   "blackMagicApplied"
               ]
            }
        }
    }
}

In the example above, would the 2nd TM "Black magic performing Thing Model" also "inheriting" the "input" and would its "output" contain properties from the extended model merged with the own defined properties?

egekorkan commented 2 months ago

Welcome back @thjaeckle ! Your example is not conforming to the first assertion but conforms to the second one. The second TM should not have the same affordance in the first place. For your use case, using tm:ref would be the only allowed solution I think. It can result in way too many tm:ref but it would be correct.

If that is not good for you, we can open the discussion to make the extension mechanism more tolerant. In that case, we will probably need a use case description from you.

thjaeckle commented 2 months ago

Thanks for the quick feedback @egekorkan (as always I would say :)).

So to summarize: It is not recommended (but not forbidden due to SHOULD NOT) that a single affordance "overwrites" an affordance inherited via tm:extends, even in a "compatible" way so that the child affordance is still valid to the parent affordance?

This I would understand from:

A Thing Model SHOULD NOT overwrite the JSON names defined within the properties, actions, and/or events Map of the extended Thing Model.

However - it still can (because only SHOULD NOT) - and then this applies?

Definitions SHOULD NOT be overwritten in such a way that possible instance values are no longer valid compared to the origin extended definitions.

As the example in Figure 6 provides exactly such an example for a property named "dim", I assume this should ;-) also work for actions and events.

egekorkan commented 2 months ago

Good points and my first comment can be ignored. In that case, your question would the 2nd TM "Black magic performing Thing Model" also "inheriting" the "input" and would its "output" contain properties from the extended model merged with the own defined properties? has the answer yes. The only issue I see there is the required array. Should the final td contain "required":["blackMagicApplied","result"]? The initial thinking says yes as the figure 6 in the spec gives the message that the data schema can become less restrictive and not more restrictive, i.e. min 5, max 95 becoming min 0 and max 100 is allowed. In your case, result key needs to be there so that the past values are not becoming invalid.

In any case, the spec should define more clearly what is a less restrictive extension and what is a more restrictive one.

thjaeckle commented 2 months ago

The only issue I see there is the required array. Should the final td contain "required":["blackMagicApplied","result"]?

Yes, I would also expect that .. Only that way, you could correctly validate the JsonSchema of the resulting TD action "output".

Yes, the spec leaves some "room for interpretation" here. But the good thing is, that the concept should still work without having to copy/repeat information from the extended model.

egekorkan commented 2 months ago

So I think that the "simple" part of this question is answered (let us know if not @thjaeckle). Looking at the bigger picture, the point " the spec should define more clearly what is a less restrictive extension and what is a more restrictive one." is important, which relates to the following points: