w3c / wot-thing-description

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

Property affoardances compact non-json-schema semantic types (@type) to json-schema `type` using the TD 1.1 @context #2041

Open SunsetFi opened 3 weeks ago

SunsetFi commented 3 weeks ago

I am resurrecting an old project based on this standard and porting it to the official TD 1.1 spec. Previously, it was pointing at a working draft copy around 2021.

With the previous spec, I was able to define both the type and the @type properties of the property affordance independently, by reserving @type for semantic types, and setting http://www.w3.org/1999/02/22-rdf-syntax-ns#type to the json schema property type.

Reviewing the changes to TD 1.1, it now appears that the json schema type property is mapped to @type directly with

"type": {
  "@id": "@type"
},

This makes it impossible to define semantic types with @type, as now every value specified on @type will be compacted to an array at type.

For example, specifying this on a property:

{
      "@type": [
        "https://www.w3.org/2019/wot/json-schema#StringSchema",
        "https://myschema#TitleProperty"
      ],
}

compacts to this:

{
      "type": [
        "string",
        "https://myschema#TitleProperty"
      ],
}

Which is invalid, as type can only be a string, not an array.

For a full example, try compacting this with https://www.w3.org/2022/wot/td/v1.1#

{
  "@id": "scenes::scene-43655d47-d1c5-4f1a-a4ed-64960f513ffa",
  "@type": [
    "https://www.w3.org/2019/wot/td#Thing"
  ],
  "https://www.w3.org/2019/wot/td#title": {
    "@language": "en",
    "@value": "scenes::scene-43655d47-d1c5-4f1a-a4ed-64960f513ffa"
  },
  "https://www.w3.org/2019/wot/td#description": {
    "@language": "en",
    "@value": "Scene"
  },
  "https://www.w3.org/2019/wot/td#hasPropertyAffordance": [
    {
      "https://www.w3.org/2019/wot/td#name": "scenes::scene-name",
      "@type": [
        "https://www.w3.org/2019/wot/json-schema#StringSchema",
        "https://myschema#TitleProperty"
      ],
      "https://www.w3.org/2019/wot/td#title": {
        "@language": "en",
        "@value": "Name"
      },
      "https://www.w3.org/2019/wot/json-schema#minLength": 1,
      "https://www.w3.org/2019/wot/json-schema#readOnly": false
    }
  ]
}

This also contradicts the documentation, where @type and type are defined independently: https://www.w3.org/TR/2023/REC-wot-thing-description11-20231205/#table-vocabulary-terms-in-dataschema-level The docs make it clear that @types is used for semantic typing, and that type is used for the json schema data type.

In practical terms, this means I can no longer apply semantic typings to my properties, as having them invade the type property causes issues with rendering the UI.

Unfortunately, the whole project is set up to pull in expanded json-ld from multiple sources and perform a final compaction operation on it, so I cannot simply ignore the context and emit the json as documented in the spec. The project relies on being able to specify everything in expanded form and have the context correctly compact the data.

Is there a way to form the expanded form of the thing definition that compacts type independently from @type? I believe I can modify the context itself to accomplish this, but would much prefer to keep pointing at the published spec instead of having to fork the definitions.

egekorkan commented 3 weeks ago

Thanks @SunsetFi for the issue. From my initial analysis, this seems to be a bug and the change happened in https://github.com/w3c/wot-thing-description/pull/1468 . @ethieblin could you comment since the PR came from you? Also tagging @mahdanoura who can help from the TF.

mahdanoura commented 3 weeks ago

I did some digging and found out there is a round tripping issue regarding the JSON-LD @type and the JSON Schema's type. Based on my analysis, this issue not only affects the properties but also the following terms: input, output, data, dataResponse, subscription and cancellation.

With the current Context file, when processing the following compact JSON-LD snippet:

{
  "@context": "https://www.w3.org/2022/wot/td/v1.1",
  "id": "scenes::scene-43655d47-d1c5-4f1a-a4ed-64960f513ffa",
  "@type": "Thing",
  "description": "Scene",
  "properties": {
    "scenes:scene-name": {
      "@type": [
        "https://myschema#TitleProperty"
      ],
      "type": "number", 
      "minLength": 1,
      "readOnly": false,
      "title": "Name"
    }
  },
  "title": "scenes:scene-43655d47-d1c5-4f1a-a4ed-64960f513ffa"
}

The type expands to:

"@type": [
          "https://myschema#TitleProperty",
          "https://www.w3.org/2019/wot/json-schema#NumberSchema"
        ]

This expansion is incorrect in my opinion, because the JSON-LD @type refers to a node type, while the JSON Schema type refers to a data value type. These should not be merged under @type.

On the other hand, when processing the expanded JSON-LD snippet:

[
  {
    "@id": "scenes::scene-43655d47-d1c5-4f1a-a4ed-64960f513ffa",
    "@type": [
      "https://www.w3.org/2019/wot/td#Thing"
    ],
    "https://www.w3.org/2019/wot/td#description": [
      {
        "@value": "Scene"
      }
    ],
    "https://www.w3.org/2019/wot/td#hasPropertyAffordance": [
      {
        "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": [
          {
            "@id": "https://www.w3.org/2019/wot/json-schema#NumberSchema"
          }], 
        "@type": [
          "https://myschema#TitleProperty"
        ]
        ,
        "https://www.w3.org/2019/wot/json-schema#minLength": [
          {
            "@value": 1
          }
        ],
        "https://www.w3.org/2019/wot/json-schema#readOnly": [
          {
            "@value": false
          }
        ],
        "https://www.w3.org/2019/wot/td#name": [
          {
            "@value": "scenes:scene-name"
          }
        ],
        "https://www.w3.org/2019/wot/td#title": [
          {
            "@value": "Name"
          }
        ]
      }
    ],
    "https://www.w3.org/2019/wot/td#title": [
      {
        "@value": "scenes:scene-43655d47-d1c5-4f1a-a4ed-64960f513ffa"
      }
    ]
  }
]

The resulting compacted JSON-LD is:

{
  "@context": "https://www.w3.org/2022/wot/td/v1.1",
  "id": "scenes::scene-43655d47-d1c5-4f1a-a4ed-64960f513ffa",
  "@type": "Thing",
  "td:description": "Scene",
  "properties": {
    "scenes:scene-name": {
      "type": "https://myschema#TitleProperty",
      "rdf:type": {
        "id": "jsonschema:NumberSchema"
      },
      "minLength": 1,
      "readOnly": false,
      "td:title": "Name"
    }
  },
  "td:title": "scenes:scene-43655d47-d1c5-4f1a-a4ed-64960f513ffa"
}

Two problems arise here. As identified by @SunsetFi the keyword type is incorrectly used instead of @type. Also, the rdf:type property is not mapped in the context, retains its full IRI form (rdf:type) in the compacted output

mahdanoura commented 3 weeks ago

The PR #1468 assigns

"type": {
  "@id": "@type"
}

which means that the JSON Schema type property should be interpreted as the JSON-LD keyword @type, that is why the JSON-LD expansion algorithm treats them as the same thing and merges them. However, apparently the JSON-LD bilt-in compaction algorithm does not treat rdf:type and @type the same.

Therefore, I think for now we should revert back to the original context which defines type as

"@id": "rdf:type",
"@type": "@vocab"

and deal with #1468 & #1466 separately.