Sebastian Kaebisch (Siemens AG) · w3.org

Abstract

This document describes a formal information model and a common representation for a Web of Things (WoT) Thing Description 1.1. A Thing Description describes the metadata and interfaces of Things, where a Thing is an abstraction of a physical or virtual entity that provides interactions to and participates in the Web of Things. Thing Descriptions provide a set of interactions based on a small vocabulary that makes it possible both to integrate diverse devices and to allow diverse applications to interoperate. Thing Descriptions, by default, are encoded in a JSON format that also allows JSON-LD processing. The latter provides a powerful foundation to represent knowledge about Things in a machine-understandable way. A Thing Description instance can be hosted by the Thing itself or hosted externally when a Thing has resource restrictions (e.g., limited memory space) or when a Web of Things-compatible legacy device is retrofitted with a Thing Description. Furthermore, this document introduces the Thing Model, which allows authors to describe only the model or class of an Internet of Things (IoT) entity. Thing Models can be seen as a template for Thing Description instances, but with reduced constraints such as no or few requirements for specific communication metadata.

This specification describes a superset of the features defined in Thing Description 1.0 [WOT-THING-DESCRIPTION10]. Unless otherwise specified, documents created with version 1.0 of this specification remain compatible with Thing Description 1.1.

Status of This Document

This section describes the status of this document at the time of its publication. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.

Future updates to this specification may incorporate new features.

The Web of Things Working Group intends to submit this document for consideration as a W3C Proposed Recommendation after at least the minimum CR review period has passed. However, before PR transition is requested, any features or assertions currently marked as at-risk that did not appear in the TD 1.0 specification and do not have at least two implementations at that time will either be removed or converted into informative statements, as appropriate.

This document was published by the Web of Things Working Group as a Recommendation using the Recommendation track.

W3C recommends the wide deployment of this specification as a standard for the Web.

A W3C Recommendation is a specification that, after extensive consensus-building, is endorsed by W3C and its Members, and has commitments from Working Group members to royalty-free licensing for implementations.

This document was produced by a group operating under the W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 03 November 2023 W3C Process Document.

Table of Contents

  1. Abstract
  2. Status of This Document
  3. 1. Introduction
    1. 1.1 Thing Description
    2. 1.2 Thing Model
  4. 2. Conformance
  5. 3. Terminology
  6. 4. Namespaces
  7. 5. TD Information Model
    1. 5.1 Overview
    2. 5.2 Preliminaries
    3. 5.3 Class Definitions
      1. 5.3.1 Core Vocabulary Definitions
        1. 5.3.1.1 Thing
        2. 5.3.1.2 InteractionAffordance
        3. 5.3.1.3 PropertyAffordance
        4. 5.3.1.4 ActionAffordance
        5. 5.3.1.5 EventAffordance
        6. 5.3.1.6 VersionInfo
        7. 5.3.1.7 MultiLanguage
      2. 5.3.2 Data Schema Vocabulary Definitions
        1. 5.3.2.1 DataSchema
        2. 5.3.2.2 ArraySchema
        3. 5.3.2.3 BooleanSchema
        4. 5.3.2.4 NumberSchema
        5. 5.3.2.5 IntegerSchema
        6. 5.3.2.6 ObjectSchema
        7. 5.3.2.7 StringSchema
        8. 5.3.2.8 NullSchema
      3. 5.3.3 Security Vocabulary Definitions
        1. 5.3.3.1 SecurityScheme
        2. 5.3.3.2 NoSecurityScheme
        3. 5.3.3.3 AutoSecurityScheme
        4. 5.3.3.4 ComboSecurityScheme
        5. 5.3.3.5 BasicSecurityScheme
        6. 5.3.3.6 DigestSecurityScheme
        7. 5.3.3.7 APIKeySecurityScheme
        8. 5.3.3.8 BearerSecurityScheme
        9. 5.3.3.9 PSKSecurityScheme
        10. 5.3.3.10 OAuth2SecurityScheme
      4. 5.3.4 Hypermedia Controls Vocabulary Definitions
        1. 5.3.4.1 Link
        2. 5.3.4.2 Form
          1. 5.3.4.2.1 Mapping op Values to Data Schemas
          2. 5.3.4.2.2 Response-related Terms Usage
        3. 5.3.4.3 ExpectedResponse
        4. 5.3.4.4 AdditionalExpectedResponse
    4. 5.4 Default Value Definitions
  8. 6. TD Representation Format
    1. 6.1 Mapping to JSON Types
    2. 6.2 Omitting Default Values
    3. 6.3 Information Model Serialization
      1. 6.3.1 Thing Root Object
      2. 6.3.2 Human-Readable Metadata
      3. 6.3.3 version
      4. 6.3.4 securityDefinitions and security
        1. 6.3.4.1 Multiple Security Definitions
        2. 6.3.4.2 security in Forms
        3. 6.3.4.3 ComboSecurityScheme
        4. 6.3.4.4 OAuth 2.0 usage
        5. 6.3.4.5 API key usage
      5. 6.3.5 properties
      6. 6.3.6 actions
      7. 6.3.7 events
      8. 6.3.8 links
      9. 6.3.9 forms
        1. 6.3.9.1 uriVariables
        2. 6.3.9.2 contentType
        3. 6.3.9.3 response
        4. 6.3.9.4 additionalResponses
        5. 6.3.9.5 contentMediaType and contentEncoding
        6. 6.3.9.6 Top level forms
      10. 6.3.10 Data Schemas
    4. 6.4 Identification
    5. 6.5 Validation
      1. 6.5.1 Minimal Validation
      2. 6.5.2 Basic Validation
      3. 6.5.3 Full Validation
  9. 7. TD Context Extensions
    1. 7.1 Semantic Annotations
      1. 7.1.1 Example I: Additional Basic Metadata
      2. 7.1.2 Example II: State Annotations
      3. 7.1.3 Example III: Geolocation Annotations
    2. 7.2 Adding Protocol Bindings
    3. 7.3 Adding Security Schemes
  10. 8. Behavioral Assertions
    1. 8.1 Security Configurations
    2. 8.2 Data Schemas
    3. 8.3 Protocol Bindings
      1. 8.3.1 Protocol Binding based on HTTP
      2. 8.3.2 Other Protocol Bindings
  11. 9. Thing Model
    1. 9.1 Basic Concept
    2. 9.2 Thing Model Declaration
    3. 9.3 Modeling Tools
      1. 9.3.1 Versioning
      2. 9.3.2 Extension and Import
      3. 9.3.3 Composition
      4. 9.3.4 tm:optional
      5. 9.3.5 Placeholder
    4. 9.4 Derivation of Thing Description Instances
    5. 9.5 Examples
  12. 10. Security Considerations
    1. 10.1 TD Interception and Tampering
    2. 10.2 Context Interception and Tampering
    3. 10.3 Limited Duration Accesses
    4. 10.4 Vulnerability Auditing
    5. 10.5 Script Injection
    6. 10.6 JSON Parsing
    7. 10.7 JSON-LD Expansion
  13. 11. Privacy Considerations
    1. 11.1 Context Fetching
    2. 11.2 Immutable Identifiers
    3. 11.3 Fingerprinting
    4. 11.4 ID Metadata
    5. 11.5 Globally Unique Identifiers
    6. 11.6 Inferencing of Personally Identifiable Information
  14. 12. IANA Considerations
    1. 12.1 application/td+json Media Type Registration
    2. 12.2 application/tm+json Media Type Registration
    3. 12.3 CoAP Content-Format Registration
      1. 12.3.1 WoT Thing Description
      2. 12.3.2 WoT Thing Model
  15. A. Example Thing Description Instances
    1. A.1 MyLampThing Example with CoAP Protocol Binding
    2. A.2 MyIlluminanceSensor Example with MQTT Protocol Binding
    3. A.3 Webhook Event Example
  16. B. JSON Schema for TD Instance Validation
  17. C. contentType usage in Thing Descriptions
  18. D. JSON-LD Context Usage
  19. E. Recent Specification Changes
    1. E.1 Changes from the Proposed Recommendation 11 July 2023
    2. E.2 Changes from the Candidate Recommendation 19 January 2023
    3. E.3 Changes from Fourth Public Working Draft 3 August 2022
    4. E.4 Changes from Third Public Working Draft 11 March 2022
    5. E.5 Changes from Second Public Working Draft 7 June 2021
    6. E.6 Changes from First Public Working Draft 24 November 2020
  20. F. Acknowledgements
  21. G. References
    1. G.1 Normative references
    2. G.2 Informative references

This section is non-normative.

The WoT Thing Description (TD) is a central building block in the W3C Web of Things (WoT) and can be considered as the entry point of a Thing (much like the index.html of a Web site). A TD instance has five main components: textual metadata about the Thing itself, a set of Interaction Affordances that indicate how the Thing can be used, schemas for the data exchanged with the Thing for machine-understandability, Security Definitions to provide metadata about the security mechanisms that must be used for interactions, and, finally, Web links to express any formal or informal relation to other Things or documents on the Web.

The Interaction Model of W3C WoT defines three types of Interaction Affordances: Properties (PropertyAffordance class) can be used for sensing and controlling parameters, such as getting the current value or setting an operation state. Actions (ActionAffordance class) model invocation of physical (and hence time-consuming) processes, but can also be used to abstract RPC-like calls of existing platforms. Events (EventAffordance class) are used for the push model of communication where notifications, discrete events, or streams of values are sent asynchronously to the receiver. See [wot-architecture11] for details.

In general, the TD provides metadata for different Protocol Bindings identified by URI schemes [RFC3986] (e.g., http, coap, etc. [IANA-URI-SCHEMES]), content types based on media types [RFC2046] (e.g., application/json, application/xml, application/cbor, application/exi, etc. [IANA-MEDIA-TYPES]), and security mechanisms (for authentication, authorization, confidentiality, etc.). Serialization of TD instances is based on JSON [RFC8259], where JSON names refer to terms of the TD vocabulary, as defined in this specification document. In addition the JSON serialization of TDs follows the syntax of JSON-LD 1.1 [JSON-LD11] to enable extensions and rich semantic processing.

Example 1 shows a TD instance and illustrates the Interaction Model with Properties, Actions, and Events by describing a lamp Thing with the title MyLampThing.

From this TD example, we know there exists one Property affordance with the title status. In addition, information is provided to indicate that this Property is accessible via (the secure form of) the HTTP protocol with a GET method at the URI https://mylamp.example.com/status (announced within the forms structure by the href member), and will return a string-based status value. The use of the GET method is not stated explicitly, but is one of the default assumptions defined by this document.

In a similar manner, an Action affordance is specified to toggle the switch status using the POST method on the https://mylamp.example.com/toggle resource, where POST is again a default assumption for invoking Actions.

The Event affordance enables a mechanism for asynchronous messages to be sent by a Thing. Here, a subscription to be notified upon a possible overheating event of the lamp can be obtained by using HTTP with its long polling subprotocol on https://mylamp.example.com/oh.

This example also specifies the basic security scheme, requiring a username and password for access. Note that a security scheme is first given a name in securityDefinitions and then activated by specifying that name in a security section. In combination with the use of the HTTP protocol this example demonstrates the use of HTTP Basic Authentication. Specification of at least one security scheme at the top level is mandatory, and gives the default access requirements for every resource. However, security schemes can also be specified per-form, with configurations given at the form level overriding configurations given at the Thing level, allowing for the specification of fine-grained access control. It is also possible to use a special nosec security scheme to indicate that no access control mechanisms are used. Additional examples will be provided later.

The Thing Description offers the possibility to add contextual definitions in some namespace. This mechanism can be used to integrate additional semantics to the content of the Thing Description instance, provided that formal knowledge, e.g., logic rules for a specific domain of application, can be found under the given namespace. Contextual information can also help specify some configurations and behavior of the underlying communication protocols declared in the forms field. Example 2 extends the TD sample from Example 1 by introducing a second definition in the @context to declare the prefix saref as referring to SAREF, the Smart Appliance Reference Ontology [SMARTM2M]. This IoT ontology includes terms interpreted as semantic labels that can be set as values of the @type field, giving the semantics of Things and their Interaction Affordances. In the example below, the Thing is labelled with saref:LightSwitch, the status Property is labelled with saref:OnOffState and the toggle Action with saref:ToggleCommand.

The declaration mechanism inside some @context is specified by JSON-LD. A TD instance complies to version 1.1 of that specification [json-ld11]. Hence, a TD instance can be also processed as an RDF document (for details about semantic processing, please refer to Appendix D. JSON-LD Context Usage and the documentation under the namespace IRIs, e.g., https://www.w3.org/2019/wot/td).

One of the main intentions of a Thing Description is to provide a Consumer with all the details necessary to successfully interact with a Thing. In some IoT application scenarios, a fully detailed Thing Description, e.g., with communication metadata is not necessary (e.g., IoT ecosystems may implicitly handle communication separately), or may not be available because a new entity has not yet been deployed (e.g., IP address is not yet known). Sometimes, also a kind of class definition is required that forces capability definitions that should be available for all created instances (e.g., large-scale production of new devices).

In order to address the above-mentioned scenarios or others, the Thing Model can be used that mainly provides the data model definitions within Things' Properties, Actions, and/or Events and can be potentially used as template for creating Thing Description instances. In the following a sample Thing Model is presented that can be seen as a model for the Thing Description instance in Example 1 .

Example 3

: Thing Model sample

{
    "@context": ["https://www.w3.org/2022/wot/td/v1.1"],
    "@type": "tm:ThingModel",
    "title": "Lamp Thing Model",
    "properties": {
        "status": {
            "description": "current status of the lamp (on|off)",
            "type": "string",
            "readOnly": true
        }
    },
    "actions": {
        "toggle": {
            "description": "Turn the lamp on or off"
        }
    },
    "events": {
        "overheating": {
            "description": "Lamp reaches a critical temperature (overheating)",
            "data": {"type": "string"}
        }
    }
}

Thing Model definitions are identified by the "@type": "tm:ThingModel". As the example shows, it does not provide details about a single Thing instance due to the lack of communication and security metadata. This specification presents a mechanism for deriving valid Thing Description instances from such Thing Model definitions. In addition, other design concepts are specified, including how to override, extend, and reuse existing Thing Model definitions.

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key words MAY, MUST, MUST NOT, RECOMMENDED, SHOULD, and SHOULD NOT in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

A Thing Description instance complies with this specification if it follows the normative statements in 5. TD Information Model and 6. TD Representation Format regarding Thing Description serialization.

A JSON Schema [JSON-SCHEMA] to validate Thing Description instances is provided in Appendix B. JSON Schema for TD Instance Validation.

This section is non-normative.

The fundamental WoT terminology such as Thing , Consumer , Producer , Thing Description ( TD ), Partial TD , Thing Model ( TM ), Interaction Model , Interaction Affordance , Property , Action , Event , Protocol Binding , Servient , Vocabulary , Term , Vocabulary Term , WoT Interface , and WoT Runtime are defined in Section 3 of the WoT Architecture specification [wot-architecture11].

In addition, this specification introduces the following definitions:

Semantic Tag , Semantic Annotation
A JSON-LD mechanism that links definitions in a Thing Descriptions document to concepts in an (RDF) ontology. This allows Thing Description authors to provide further context and express domain knowledge in a standardized way. In a Thing Descriptions document, this can be achieved using @type members, and through the use of string prefixes using a colon (:).
TD Context Extension
A mechanism to extend Thing Descriptions with additional Vocabulary Terms. It is the basis for semantic annotations and extensions to core mechanisms such as Protocol Bindings, Security Schemes, and Data Schemas.
TD Information Model
Set of Class definitions constructed from pre-defined Vocabularies on which constraints apply, thus defining the semantics of these Vocabularies. Class definitions are typically expressed in terms of a Signature (a set of Vocabulary Terms) and functions over that Signature. The TD Information Model also includes Default Values, defined as a global function over Classes.
TD Processor
A system that can serialize some internal representation of a Thing Description in a given format and/or deserialize it from that format. A TD Processor can follow validation steps to detect semantically inconsistent Thing Descriptions, that is, Thing Descriptions that cannot satisfy constraints on the Instance Relation of the Thing class. For that purpose, a TD Processor can compute fill in the forms of Thing Descriptions in which all possible Default Values are assigned. A TD Processor is typically a sub-system of a WoT Runtime. Implementations of a TD Processor can be a TD producer (able to serialize to TD Documents) or a TD consumer (able to deserialize from TD Documents) or both.
TD Serialization or TD Document
Textual or binary representation of Thing Descriptions that can be stored and exchanged between Servients. A TD Serialization follows a given representation format, identified by a media type when exchanged over the network. The default representation format for Thing Descriptions is JSON-based as defined by this specification.
Levels of a TD (including Thing Level , Affordance Level , Data Schema Level , Forms Level )
The scope of a TD or TM instance at the given hierarchy level. For example, the root of a TD, where terms such as @context are defined is the Thing level, forms are defined within the Affordance level, type, maximum are defined within the Data Schema level and href is defined within the Forms level. Even if not defined, other levels can be used such as Links level.

These definitions are further developed in 5.2 Preliminaries.

The version of the TD Information Model defined in 5. TD Information Model of this specification is identified by the following IRI:

https://www.w3.org/2022/wot/td/v1.1

This IRI [RFC3987], which is also a URI [RFC3986], can be dereferenced to obtain a JSON-LD context file [json-ld11], allowing the compact strings in TD Documents to be expanded to full IRI-based Vocabulary Terms. However, this processing is only required when transforming JSON-based TD Documents to RDF, an optional feature of TD Processor implementations.

In the present specification, Vocabulary Terms are always presented in their compact form. Their expanded form can be accessed under the namespace IRI of the Vocabulary they belong to. These namespaces follow the structure of 5.3 Class Definitions. Each Vocabulary used in the TD Information Model has its own namespace IRI, as follows:

Table 1 Namespaces used in TDs
Vocabulary Namespace IRI
Core https://www.w3.org/2019/wot/td#
Data Schema https://www.w3.org/2019/wot/json-schema#
Security https://www.w3.org/2019/wot/security#
Hypermedia Controls https://www.w3.org/2019/wot/hypermedia#

All vocabularies that are additionally used for Thing Model definitions have the following namespace IRI:

Table 2 Namespaces used in TMs
Vocabulary Namespace IRI
Thing Model https://www.w3.org/2022/wot/tm#

The Vocabularies are independent from each other. They may be reused and extended in other W3C specifications. Every breaking change in the design of a Vocabulary will require the assignment of a new year-based namespace URI. Note that to maintain the general coherence of the TD Information Model, the associated JSON-LD context file is versioned such that every version has its own URI (v1, v1.1, v2, ...) to also identify non-breaking changes, in particular the addition of new Terms.

Because a Vocabulary under some namespace IRI can only undergo non-breaking changes, its content can be safely cached or embedded in applications. One advantage of exposing relatively static content under a namespace IRI is to optimize payload sizes of messages exchanged between constrained devices. It also avoids any privacy leakage resulting from devices accessing publicly available vocabularies from private networks (see also 11. Privacy Considerations).

This section introduces the TD Information Model. The TD Information Model serves as the conceptual basis for the processing of Thing Descriptions and their serialization, which is described separately in 6. TD Representation Format.

The TD Information Model is built upon the following, independent Vocabularies:

Each of these Vocabularies is essentially a set of Terms that can be used to build data structures, interpreted as objects in the traditional object-oriented sense. Objects are instances of classes and have properties. In the context of W3C WoT, they denote Things and their Interaction Affordances. A formal definition of objects is given in 5.2 Preliminaries. The main elements of the TD Information Model are then presented in 5.3 Class Definitions. Certain object properties may be omitted in a TD when Default Values exist. A list of defaults is given in 5.4 Default Value Definitions.

The UML diagram shown next gives an overview of the TD Information Model. It represents all classes as tables and the associations that exist between classes, starting from the class Thing, as directed arrows. For the sake of readability, the diagram was split in four parts, one for each of the four base Vocabularies.

UML diagram of the TD information model for the TD core vocabulary
Figure 1 TD core vocabulary

UML diagram of the TD information model for the Data schema vocabulary
Figure 2 Data schema vocabulary

UML diagram of the TD information model for the WoT security vocabulary
Figure 3 WoT security vocabulary

UML diagram of the TD information model for the hypermedia controls vocabulary
Figure 4 Hypermedia controls vocabulary

To provide a model that can be easily processed by both, simple rules on a tree-based document (i.e., raw JSON processing) and rich Semantic Web tooling (i.e., JSON-LD processing), this document defines the following formal preliminaries to construct the TD Information Model accordingly.

All definitions in this section refer to sets, which intuitively are collections of elements that can themselves be sets. All arbitrarily complex data structures can be defined in terms of sets. In particular, an Object is a data structure recursively defined as follows:

Though this definition does not prevent Objects to include multiple name-value pairs with the same name, they are generally not considered in this specification. An Object whose elements only have numbers as names is called an Array . Similarly, an Object whose elements only have Terms (that do not belong to any Vocabulary) as names is called a Map . All names appearing in some name-value pair in a Map are assumed to be unique within the scope of the Map.

Moreover, Objects can be instances of some Class . A Class, which is denoted by a Vocabulary Term, is first defined by a set of Vocabulary Terms called a Signature . A Class whose Signature is empty is called a Simple Type .

The Signature of a Class allows to construct two functions that further define Classes: an Assignment Function and a Type Function . The Assignment Function of a Class takes a Vocabulary Term of the Class's Signature as input and returns either true or false as output. Intuitively, the Assignment Function indicates whether an element of the Signature is mandatory or optional when instantiating the Class. The Type Function of a Class also takes a Vocabulary Term of the Class's Signature as input and returns another Class as output. These functions are partial: their domain is limited to the Signature of the Class being defined.

On the basis of these two functions, an Instance Relation can be defined for a pair composed of an Object and a Class. This relation is defined as constraints to be satisfied. That is, an Object is an instance of a Class if the two following constraints are both satisfied:

According to the definition above, an Object would be an instance of every Simple Type, regardless of its structure. Instead, another definition for the Instance Relation is introduced for Simple Types: an Object is an instance of a Simple Type if it is a Term with a given lexical form (e.g., true, false for the boolean type, 1, 2, 3, ... for the unsignedInt type, etc.).

Moreover, additional Classes, called Parameterized Classes , can be derived from the generic Map and Array structures. An Object is a Map of some Class, that is, an instance of the Map type parameterized with some Class, if it is a Map such that the value in all the name-value pairs it contains is an instance of this Class. The same applies to Arrays.

Finally, a Class is a Subclass of some other Class if every instance of the former is also an instance of the latter.

Given all definitions above, the TD Information Model is to be understood as a set of Class definitions, which include a Class name (a Vocabulary Term), a Signature (a set of Vocabulary Terms), an Assignment Function, and a Type Function. These Class definitions are provided as tables in 5.3 Class Definitions. For each table, the values "mandatory" (respectively, "optional") in the assignment column indicates that the Assignment Function returns true (respectively, false) for the corresponding Vocabulary Term.

By convention, Simple Types are denoted by names starting with lowercase. The TD Information Model references the following Simple Types defined in XML Schema [XMLSCHEMA11-2-20120405]: string, anyURI, dateTime, integer, unsignedInt, double, and boolean. Their definition (i.e., the specification of their lexical form) is outside of the scope of the TD Information Model.

In addition, the TD Information Model defines a global function on pairs of Vocabulary Terms. The function takes a Class name and another Vocabulary Term as input and returns an Object. If the returned Object is different from null, it represents the Default Value for some assignment on the input Vocabulary Term in an instance of the input Class. This function allows to relax the constraint defined above on the Assignment Function: an Object is an instance of a Class if it includes all mandatory assignments or if Default Value exist for the missing assignments. All Default Values are given in the table of 5.4 Default Value Definitions. In each table of 5.3 Class Definitions, the assignment column contains the value "with default" if a Default Value is available for the corresponding combination of Class and Vocabulary Term in the TD Information Model.

The formalization introduced here does not consider the possible relation between Objects as abstract data structures and physical world objects such as Things. However, care was given to the possibility of re-interpreting all Vocabulary Terms involved in the TD Information Model as RDF resources, so as to integrate them in a larger model of the physical world (an ontology). For details about semantic processing, please refer to D. JSON-LD Context Usage and the documentation under the namespace IRIs, e.g., https://www.w3.org/2019/wot/td.

A TD Processor MUST satisfy the Class instantiation constraints on all Classes defined in 5.3.1 Core Vocabulary Definitions, 5.3.2 Data Schema Vocabulary Definitions, 5.3.3 Security Vocabulary Definitions, and 5.3.4 Hypermedia Controls Vocabulary Definitions.

In particular, note that all vocabulary terms and values are case sensitive. This is also true for the serialization of the information model (Section 6. TD Representation Format).

An abstraction of a physical or a virtual entity whose metadata and interfaces are described by a WoT Thing Description, whereas a virtual entity is the composition of one or more Things.

Table 3 Vocabulary Terms in Thing Level
Vocabulary term Description Assignment Type
@context JSON-LD keyword to define short-hand names called terms that are used throughout a TD document. mandatory anyURI or Array
@type JSON-LD keyword to label the object with semantic tags (or types). optional string or Array of string
id Identifier of the Thing in form of a URI [RFC3986] (e.g., stable URI, temporary and mutable URI, URI with local IP address, URN, etc.). optional anyURI
title Provides a human-readable title (e.g., display a text for UI representation) based on a default language. mandatory string
titles Provides multi-language human-readable titles (e.g., display a text for UI representation in different languages). Also see MultiLanguage. optional Map of MultiLanguage
description Provides additional (human-readable) information based on a default language. optional string
descriptions Can be used to support (human-readable) information in different languages. Also see MultiLanguage. optional Map of MultiLanguage
version Provides version information. optional VersionInfo
created Provides information when the TD instance was created. optional dateTime
modified Provides information when the TD instance was last modified. optional dateTime
support Provides information about the TD maintainer as URI scheme (e.g., mailto [RFC6068], tel [RFC3966], https [RFC9112]). optional anyURI
base Define the base URI that is used for all relative URI references throughout a TD document. In TD instances, all relative URIs are resolved relative to the base URI using the algorithm defined in [RFC3986].

base does not affect the URIs used in @context and the IRIs used within Linked Data [LINKED-DATA] graphs that are relevant when semantic processing is applied to TD instances.

optional anyURI
properties All Property-based Interaction Affordances of the Thing. optional Map of PropertyAffordance
actions All Action-based Interaction Affordances of the Thing. optional Map of ActionAffordance
events All Event-based Interaction Affordances of the Thing. optional Map of EventAffordance
links Provides Web links to arbitrary resources that relate to the specified Thing Description. optional Array of Link
forms Set of form hypermedia controls that describe how an operation can be performed. Forms are serializations of Protocol Bindings. Thing level forms are used to describe endpoints for a group of interaction affordances. optional Array of Form
security Set of security definition names, chosen from those defined in securityDefinitions. These must all be satisfied for access to resources. mandatory string or Array of string
securityDefinitions Set of named security configurations (definitions only). Not actually applied unless names are used in a security name-value pair. mandatory Map of SecurityScheme
profile Indicates the WoT Profile mechanisms followed by this Thing Description and the corresponding Thing implementation. optional anyURI or Array of anyURI
schemaDefinitions Set of named data schemas. To be used in a schema name-value pair inside an AdditionalExpectedResponse object. optional Map of DataSchema
uriVariables Define URI template variables according to [RFC6570] as collection based on DataSchema declarations. The Thing level uriVariables can be used in Thing level forms or in Interaction Affordances. The individual variables DataSchema cannot be an ObjectSchema or an ArraySchema since each variable needs to be serialized to a string inside the href upon the execution of the operation. If the same variable is both declared in Thing level uriVariables and in Interaction Affordance level, the Interaction Affordance level variable takes precedence. optional Map of DataSchema

For @context the following rules are defined for Thing Description instances:

  • The @context name-value pair MUST contain the anyURI https://www.w3.org/2022/wot/td/v1.1 in order to identify the document as a TD 1.1 which would allow Consumers to use the newly introduced terms.
  • When there are possibly TD 1.0 consumers the anyURI https://www.w3.org/2019/wot/td/v1 MUST be the first entry and the https://www.w3.org/2022/wot/td/v1.1 MUST be the second entry.
  • TD 1.1 consumers MUST accept TDs satisfying the W3C WoT Thing Description 1.0 [wot-thing-description10] specification.
  • When @context is an Array, the anyURI https://www.w3.org/2022/wot/td/v1.1 MAY be followed by elements of type anyURI or type Map in any order, while it is RECOMMENDED to include only one Map with all the name-value pairs in the @context Array.
  • Maps contained in an @context Array MAY contain name-value pairs, where the value is a namespace identifier of type anyURI and the name a Term or prefix denoting that namespace.
  • One Map contained in an @context Array SHOULD contain a name-value pair that defines the default language for the Thing Description, where the name is the Term @language and the value is a well-formed language tag as defined by [BCP47] (e.g., en, de-AT, gsw-CH, zh-Hans, zh-Hant-HK, sl-nedis).

To determine the base direction of all human-readable text in Thing Description and Thing Model instances this specification recommends to follow the [STRING-META] guideline about string-specific directional information when no built-in mechanism for associating base direction metadata is available.

TD Processors should be aware of certain special cases when processing bidirectional text. TD Processors SHOULD take care to use bidi isolation when presenting strings to users, particularly when embedding in surrounding text (e.g., for Web user interface). Mixed direction text can occur in any language, even when the language is properly identified.

TD producers SHOULD attempt to provide mixed direction strings in a way that can be displayed successfully by a naive user agent. For example, if an RTL string begins with an LTR run (such as a number or a brand or trade name in Latin script), including an RLM character at the start of the string or wrapping opposite direction runs in bidi controls can assist in proper display.

Strings on the Web: Language and Direction Metadata [string-meta] provides some guidance and illustrates a number of pitfalls when using bidirectional text.

In addition to the explicitly provided Interaction Affordances in the properties, actions, and events Maps, a Thing can also provide meta-interactions, which are indicated by Form instances in its optional forms Array. When the forms Array of a Thing instance contains Form instances, it MUST contain op member with the string values assigned to the name op, either directly or within an Array, MUST be one of the following operation types: readallproperties, writeallproperties, readmultipleproperties, writemultipleproperties, observeallproperties, unobserveallproperties, queryallactions, subscribeallevents, or unsubscribeallevents. (See an example for an usage of form in a Thing instance.)

The data schema for each of the property meta-interactions is constructed by combining the data schemas of each PropertyAffordance instance in a single ObjectSchema instance, where the properties Map of the ObjectSchema instance contains each data schema of the PropertyAffordances identified by the name of the corresponding PropertyAffordances instance.

If not specified otherwise (e.g., through a TD Context Extension), the request data of the readmultipleproperties operation is an Array that contains the intended PropertyAffordances instance names, which is serialized to the content type specified by the Form instance.

Metadata of a Thing that shows the possible choices to Consumers, thereby suggesting how Consumers may interact with the Thing. There are many types of potential affordances, but W3C WoT defines three types of Interaction Affordances: Properties, Actions, and Events.

Table 4 Vocabulary Terms in InteractionAffordance Level
Vocabulary term Description Assignment Type
@type JSON-LD keyword to label the object with semantic tags (or types). optional string or Array of string
title Provides a human-readable title (e.g., display a text for UI representation) based on a default language. optional string
titles Provides multi-language human-readable titles (e.g., display a text for UI representation in different languages). Also see MultiLanguage. optional Map of MultiLanguage
description Provides additional (human-readable) information based on a default language. optional string
descriptions Can be used to support (human-readable) information in different languages. Also see MultiLanguage. optional Map of MultiLanguage
forms Set of form hypermedia controls that describe how an operation can be performed. Forms are serializations of Protocol Bindings. The array cannot be empty. mandatory Array of Form
uriVariables Define URI template variables according to [RFC6570] as collection based on DataSchema declarations. The individual variables DataSchema cannot be an ObjectSchema or an ArraySchema since each variable needs to be serialized to a string inside the href upon the execution of the operation. If the same variable is both declared in Thing level uriVariablesand in Interaction Affordance level, the Interaction Affordance level variable takes precedence. optional Map of DataSchema

The class InteractionAffordance has the following subclasses:

An Interaction Affordance that exposes state of the Thing. This state can then be retrieved (read) and/or updated (write). Things can also choose to make Properties observable by pushing the new state after a change.

Table 5 Vocabulary Terms in PropertyAffordance Level
Vocabulary term Description Assignment Type
observable A hint that indicates whether Servients hosting the Thing and Intermediaries should provide a Protocol Binding that supports the observeproperty and unobserveproperty operations for this Property. with default boolean

Note

Property instances are also instances of the class DataSchema. Therefore, it can contain the type, unit, readOnly and writeOnly members, among others.

PropertyAffordance is a Subclass of the InteractionAffordance Class and the DataSchema Class. When a Form instance is within a PropertyAffordance instance, the value assigned to op MUST be one of readproperty, writeproperty, observeproperty, unobserveproperty or an Array containing a combination of these terms.

Note

It is considered to be good practice that each observeproperty has a corresponding unobserveproperty unless the protocol supports implicit unsubscription mechanisms (e.g., heartbeat to detect connection loss).

Note

The observation mechanism depends on the underlying protocol or sub-protocol. Having said that, it is not guaranteed that the current Property value will be provided once the subscription is initiated. Hence, it may be necessary to read the current Property value before/after the subscription to get a first value.

An Interaction Affordance that allows to invoke a function of the Thing, which manipulates state (e.g., toggling a lamp on or off) or triggers a process on the Thing (e.g., dim a lamp over time).

Table 6 Vocabulary Terms in ActionAffordance Level
Vocabulary term Description Assignment Type
input Used to define the input data schema of the Action. optional DataSchema
output Used to define the output data schema of the Action. optional DataSchema
safe Signals if the Action is safe (=true) or not. Used to signal if there is no internal state (cf. resource state) is changed when invoking an Action. In that case responses can be cached as example. with default boolean
idempotent Indicates whether the Action is idempotent (=true) or not. Informs whether the Action can be called repeatedly with the same result, if present, based on the same input. with default boolean
synchronous Indicates whether the action is synchronous (=true) or not. A synchronous action means that the response of action contains all the information about the result of the action and no further querying about the status of the action is needed. Lack of this keyword means that no claim on the synchronicity of the action can be made. optional boolean

ActionAffordance is a Subclass of the InteractionAffordance Class. When a Form instance is within an ActionAffordance instance, the value assigned to op MUST either be invokeaction, queryaction, cancelaction or an Array containing a combination of these terms.

An Interaction Affordance that describes an event source, which asynchronously pushes event data to Consumers (e.g., overheating alerts).

Table 7 Vocabulary Terms in EventAffordance Level
Vocabulary term Description Assignment Type
subscription Defines data that needs to be passed upon subscription, e.g., filters or message format for setting up Webhooks. optional DataSchema
data Defines the data schema of the Event instance messages pushed by the Thing. optional DataSchema
dataResponse Defines the data schema of the Event response messages sent by the consumer in a response to a data message. optional DataSchema
cancellation Defines any data that needs to be passed to cancel a subscription, e.g., a specific message to remove a Webhook. optional DataSchema

EventAffordance is a Subclass of the InteractionAffordance Class. When a Form instance is within an EventAffordance instance, the value assigned to op MUST be either subscribeevent, unsubscribeevent, or both terms within an Array.

Note

It is considered to be good practice that each subscribeevent has a corresponding unsubscribeevent unless the protocol supports implicit unsubscription mechanisms (e.g., heartbeat to detect connection loss).

Metadata of a Thing that provides version information about the TD document. If required, additional version information such as firmware and hardware version (term definitions outside of the TD namespace) can be extended via the TD Context Extension mechanism.

Table 8 Vocabulary Terms in VersionInfo Level
Vocabulary term Description Assignment Type
instance Provides a version indicator of this TD. mandatory string
model Provides a version indicator of the underlying TM. optional string

It is recommended that the values within instances and model of the VersionInfo Class follow the semantic versioning pattern, where a sequence of three numbers separated by a dot indicates the major version, minor version, and patch version, respectively. See [SEMVER] for details.

A Map providing a set of human-readable texts in different languages identified by language tags described in [BCP47]. See 6.3.2 Human-Readable Metadata for example usages of this container in a Thing Description instance.

Each name of the MultiLanguage Map MUST be a language tag as defined in [BCP47]. Each value of the MultiLanguage Map MUST be of type string.

A data schema is an abstract notation for data contained in data formats.

The data schema vocabulary definition reflects a very common subset of the terms defined by JSON Schema [JSON-SCHEMA]. A JSON Schema [JSON-SCHEMA] processor for JSON Schema draft 7 can consume a data schema. It is noted that data schema definitions within Thing Description instances are not limited to this defined subset and may use additional terms found in JSON Schema using a TD Context Extension for the additional terms as described in 7. TD Context Extensions, otherwise these terms are semantically ignored by TD Processors (for details about semantic processing, please refer to D. JSON-LD Context Usage and the documentation under the namespace IRIs, e.g., https://www.w3.org/2019/wot/td).

In a TD, concrete data formats are specified in Forms (see 5.3.4.2 Form) using content types. When the value of a content type in an instance of the Form is application/json, the data schema can be processed directly by JSON Schema processors. Otherwise, Web of Things (WoT) Binding Templates [WOT-BINDING-TEMPLATES] defines data schema's available mappings to other content types such as XML [xml]. If the content type in an instance of the Form is not application/json and if no mapping is defined for the content type, specifying a data schema does not make sense for the content type.

The following table contains content types which MAY use data schema to describe the structure of their payloads.

Table 9 Content types that can use a Data Schema
Format Content Type
JSON/CBOR application/json
application/ld+json
application/senml+json
application/cbor
application/senml+cbor
XML/EXI application/xml
application/senml+xml
application/exi
application/senml-exi

Metadata that describes the data format used. It can be used for validation.

Table 10 Vocabulary Terms in DataSchema Level
Vocabulary term Description Assignment Type
@type JSON-LD keyword to label the object with semantic tags (or types) optional string or Array of string
title Provides a human-readable title (e.g., display a text for UI representation) based on a default language. optional string
titles Provides multi-language human-readable titles (e.g., display a text for UI representation in different languages). Also see MultiLanguage. optional Map of MultiLanguage
description Provides additional (human-readable) information based on a default language. optional string
descriptions Can be used to support (human-readable) information in different languages. Also see MultiLanguage. optional Map of MultiLanguage
const Provides a constant value. optional any type
default Supply a default value. The value SHOULD validate against the data schema in which it resides. optional any type
unit Provides unit information that is used, e.g., in international science, engineering, and business. To preserve uniqueness, it is recommended that the value of the unit points to a semantic definition (also see Section Semantic Annotations). optional string
oneOf Used to ensure that the data is valid against one of the specified schemas in the array. This can be used to describe multiple input or output schemas. optional Array of DataSchema
enum Restricted set of values provided as an array. optional Array of any type
readOnly Boolean value that is a hint to indicate whether a property interaction / value is read only (=true) or not (=false). with default boolean
writeOnly Boolean value that is a hint to indicate whether a property interaction / value is write only (=true) or not (=false). with default boolean
format Allows validation based on a format pattern such as "date-time", "email", "uri", etc. (Also see below.) optional string
type Assignment of JSON-based data types compatible with JSON Schema (one of boolean, integer, number, string, object, array, or null). optional string (one of object, array, string, number, integer, boolean, or null)

The class DataSchema has the following subclasses:

The format string values are known from a fixed set of values and their corresponding format rules defined in [JSON-SCHEMA] (Section 7.3 Defined Formats in particular). Servients MAY use the format value to perform additional validation accordingly. When a value that is not found in the known set of values is assigned to format, such a validation SHOULD succeed.

Vocabulary terms typed as any type (e.g., const, default) follow data types compatible with JSON Schema (boolean, integer, number, string, object, array, or null).

Note

The format term is not widely implemented by JSON Schema tools. In addition, the term format is being discussed by the JSON Schema standardisation community and may be replaced by another mechanism or removed in a future JSON Schema version.

Metadata describing data of type Array. This Subclass is indicated by the value array assigned to type in DataSchema instances.

Table 11 Vocabulary Terms in ArraySchema Level
Vocabulary term Description Assignment Type
items Used to define the characteristics of an array. optional DataSchema or Array of DataSchema
minItems Defines the minimum number of items that have to be in the array. optional unsignedInt
maxItems Defines the maximum number of items that have to be in the array. optional unsignedInt

Metadata describing data of type boolean. This Subclass is indicated by the value boolean assigned to type in DataSchema instances.

Metadata describing data of type number. This Subclass is indicated by the value number assigned to type in DataSchema instances.

Table 12 Vocabulary Terms in NumberSchema Level
Vocabulary term Description Assignment Type
minimum Specifies a minimum numeric value, representing an inclusive lower limit. Only applicable for associated number or integer types. optional double
exclusiveMinimum Specifies a minimum numeric value, representing an exclusive lower limit. Only applicable for associated number or integer types. optional double
maximum Specifies a maximum numeric value, representing an inclusive upper limit. Only applicable for associated number or integer types. optional double
exclusiveMaximum Specifies a maximum numeric value, representing an exclusive upper limit. Only applicable for associated number or integer types. optional double
multipleOf Specifies the multipleOf value number. The value must strictly greater than 0. Only applicable for associated number or integer types. optional double

Metadata describing data of type integer. This Subclass is indicated by the value integer assigned to type in DataSchema instances.

Table 13 Vocabulary Terms in IntegerSchema Level
Vocabulary term Description Assignment Type
minimum Specifies a minimum numeric value, representing an inclusive lower limit. Only applicable for associated number or integer types. optional integer
exclusiveMinimum Specifies a minimum numeric value, representing an exclusive lower limit. Only applicable for associated number or integer types. optional integer
maximum Specifies a maximum numeric value, representing an inclusive upper limit. Only applicable for associated number or integer types. optional integer
exclusiveMaximum Specifies a maximum numeric value, representing an exclusive upper limit. Only applicable for associated number or integer types. optional integer
multipleOf Specifies the multipleOf value number. The value must strictly greater than 0. Only applicable for associated number or integer types. optional integer

Metadata describing data of type Object. This Subclass is indicated by the value object assigned to type in DataSchema instances.

Table 14 Vocabulary Terms in ObjectSchema Level
Vocabulary term Description Assignment Type
properties Data schema nested definitions. optional Map of DataSchema
required Defines which members of the object type are mandatory, i.e. which members are mandatory in the payload that is to be sent (e.g. input of invokeaction, writeproperty) and what members will be definitely delivered in the payload that is being received (e.g. output of invokeaction, readproperty) optional Array of string

Metadata describing data of type string. This Subclass is indicated by the value string assigned to type in DataSchema instances.

Table 15 Vocabulary Terms in StringSchema Level
Vocabulary term Description Assignment Type
minLength Specifies the minimum length of a string. Only applicable for associated string types. optional unsignedInt
maxLength Specifies the maximum length of a string. Only applicable for associated string types. optional unsignedInt
pattern Provides a regular expression to express constraints of the string value. The regular expression must follow the [ECMA-262] dialect. optional string
contentEncoding Specifies the encoding used to store the contents, as specified in [RFC2045] (Section 6.1) and [RFC4648]. optional string (e.g., 7bit, 8bit, binary, quoted-printable, base16, base32, or base64)
contentMediaType Specifies the MIME type of the contents of a string value, as described in [RFC2046]. optional string (e.g., image/png, or audio/mpeg)

Note

The length of a string (i.e., minLength and maxLength) is defined as the number of Unicode code points, as defined by [RFC8259]. Note that some user-perceived characters are composed of more than one Unicode code point. Arbitrary index values might not fall on these grapheme boundaries, so truncation according to maxLength might alter the appearance or meaning of the string.

Metadata describing data of type null. This subclass is indicated by the value null assigned to type in DataSchema instances. This Subclass describes only one acceptable value, namely null. It is important to note that null does not mean the absence of a value. It is analogous to null in JavaScript, None in Python, null in Java and nil in Ruby programming languages. It can be used as part of a oneOf declaration, where it is used to indicate, that the data can also be null.

This specification provides a selection of well-established security mechanisms that are directly built into protocols eligible as Protocol Bindings for W3C WoT or are widely in use with those protocols. The current set of HTTP security schemes is partly based on OpenAPI 3.0.1 (see also [OPENAPI]). However while the HTTP security schemes, Vocabulary, and syntax given in this specification share many similarities with OpenAPI, they are not compatible.

Generally, security schemes require some form of secure transport to be effective, such as TLS or DTLS. Requirements for the use of secure transport are given in Section 10. Security Considerations in this document and in the Security Considerations section of [wot-architecture11].

Metadata describing the configuration of a security mechanism. The value assigned to the name scheme MUST be defined within a Vocabulary included in the Thing Description, either in the standard Vocabulary defined in §  5. TD Information Model or in a TD Context Extension.

For all security schemes, any keys, passwords, or other sensitive information directly providing access MUST NOT be stored in the TD and should instead be shared and stored out-of-band via other mechanisms. The purpose of a TD is to describe how to access a Thing if and only if a Consumer already has authorization, and is not meant be used to grant that authorization.

Each security scheme object used in a TD defines a set of requirements to be met before access can be granted. We say a security scheme is satisfied when all its requirements are met. In some cases requirements from multiple security schemes will have to be met before access can be granted.

Security schemes generally may require additional authentication parameters, such as a password or key. The location of this information is indicated by the value associated with the name in, often in combination with the value associated with name. The value associated with in can take one of the following values:

header:
The parameter will be given in a header provided by the protocol, with the name of the header provided by the value of name.
query:
The parameter will be appended to the URI as a query parameter, with the name of the query parameter provided by name.
body:
The parameter will be provided in the body of the request payload, with the data schema element used provided by name. When used in the context of a body security information location, the value of name MUST be in the form of a JSON pointer [RFC6901] relative to the root of the input DataSchema for each interaction it is used with. Since this value is not a fragment identifier, and is not relative to the root of the TD but to whichever data schemas the security scheme is bound to, this value should not start with #; it is a "pure" JSON pointer. Since this value is not a fragment identifier, it also does not need to URL-encode special characters. The targeted element may or may not already exist at the specified location in the referenced object or array schema (consequently the mechanism is not applicable to simple types). If it does not, it will be inserted. This avoids having to duplicate definitions in the data schemas of every interaction. When an element of a data schema indicated by a JSON pointer indicated in a body locator does not already exist in the indicated schema, it MUST be possible to insert the indicated element at the location indicated by the pointer. The JSON pointer used in the body locator MAY use the "-" character to indicate a non-existent array element when it is necessary to insert an element after the last element of an existing array. The element referenced (or created) by a body security information location MUST be required and of type "string". If name is not given, it is assumed the entire body is to be used as the security parameter.
cookie:
The parameter is stored in a cookie identified by the value of name.
uri:
The parameter is embedded in the URI itself, which is encoded in the relevant interaction using a URI template variable defined by the value of name. This is more general than the query mechanism but more complex. The value uri SHOULD be specified for the name in in a security scheme only if query is not applicable. The URIs provided in interactions where a security scheme using uri as the value for in MUST be a URI template including the defined variable.
auto:
The location is determined as part of the protocol, or negotiated. If a value of auto is set for the in field of a SecurityScheme, then the name field SHOULD NOT be set. In this case, the application of the SecurityScheme is subject to the respective specification for the given protocol (e.g. [RFC8288] when using the BasicSecurityScheme with HTTP).

If multiple parameters are needed for a security scheme, repeat the security scheme definition for each parameter and combine them using a combo security scheme and allOf. In some cases parameters may not actually be secret but a user may wish to leave them out of the TD to help protect privacy. As an example of this, some security mechanisms require both a client identifier and a secret key. In theory, the client identifier is public however it may be hard to update and pose a tracking risk. In such a case it can be provided as an additional security parameter so it does not appear in the TD.

The names of URI variables declared in a SecurityScheme MUST be distinct from all other URI variables declared in the TD.

Table 16 Vocabulary Terms in SecurityScheme Level
Vocabulary term Description Assignment Type
@type JSON-LD keyword to label the object with semantic tags (or types). optional string or Array of string
description Provides additional (human-readable) information based on a default language. optional string
descriptions Can be used to support (human-readable) information in different languages. Also see MultiLanguage. optional Map of MultiLanguage
proxy URI of the proxy server this security configuration provides access to. If not given, the corresponding security configuration is for the endpoint. optional anyURI
scheme Identification of the security mechanism being configured. mandatory string (e.g., nosec, combo, basic, digest, bearer, psk, oauth2, apikey, or auto)

The class SecurityScheme has the following subclasses:

A security configuration corresponding to identified by the Vocabulary Term nosec (i.e., "scheme": "nosec"), indicating there is no authentication or other mechanism required to access the resource.

An automatic authentication security configuration identified by the term auto (i.e., "scheme": "auto"). This scheme indicates that the security parameters are going to be negotiated by the underlying protocols at runtime, subject to the respective specifications for the protocol (e.g. [RFC8288] for Basic Authentication when using HTTP).

A combination of other security schemes identified by the Vocabulary Term combo (i.e., "scheme": "combo"). Elements of this scheme define various ways in which other named schemes defined in securityDefinitions, including other ComboSecurityScheme definitions, are to be combined to create a new scheme definition. Exactly one of either oneOf or allOf vocabulary terms MUST be included. Only security scheme definitions which can be used together can be combined with allOf. For example, it is not possible in general to combine different OAuth 2.0 flows together using allOf unless one applies to a proxy and one to the endpoint. Note that when multiple named security scheme definitions are listed in a security field the same semantics apply as in an allOf combination (and the same limitations on allowable combinations). The oneOf combination is equivalent to using different security schemes on forms that are otherwise identical. In this sense a oneOf scheme is not an essential feature but it does avoid redundancy in such cases.

Table 17 Vocabulary Terms in ComboSecurityScheme Level
Vocabulary term Description Assignment Type
oneOf Array of two or more strings identifying other named security scheme definitions, any one of which, when satisfied, will allow access. Only one may be chosen for use. mandatory Array of string
allOf Array of two or more strings identifying other named security scheme definitions, all of which must be satisfied for access. mandatory Array of string

Basic Authentication [RFC7617] security configuration identified by the Vocabulary Term basic (i.e., "scheme": "basic"), using an unencrypted username and password.

Table 18 Vocabulary Terms in BasicSecurityScheme Level
Vocabulary term Description Assignment Type
name Name for query, header, cookie, or uri parameters. optional string
in Specifies the location of security authentication information. with default string (one of header, query, body, cookie, or auto)

Digest Access Authentication [RFC7616] security configuration identified by the Vocabulary Term digest (i.e., "scheme": "digest"). This scheme is similar to basic authentication but with added features to avoid man-in-the-middle attacks.

Table 19 Vocabulary Terms in DigestSecurityScheme Level
Vocabulary term Description Assignment Type
name Name for query, header, cookie, or uri parameters. optional string
in Specifies the location of security authentication information. with default string (one of header, query, body, cookie, or auto)
qop Quality of protection. with default string (one of auth, or auth-int)

API key authentication security configuration identified by the Vocabulary Term apikey (i.e., "scheme": "apikey"). This scheme is to be used when the access token is opaque, for example when a key in an unknown or proprietary format is provided by a cloud service provider. In this case the key may not be using a standard token format. This scheme indicates that the key provided by the service provider needs to be supplied as part of service requests using the mechanism indicated by the "in" field.

Table 20 Vocabulary Terms in APIKeySecurityScheme Level
Vocabulary term Description Assignment Type
name Name for query, header, cookie, or uri parameters. optional string
in Specifies the location of security authentication information. with default string (one of header, query, body, cookie, uri, or auto)

Bearer Token [RFC6750] security configuration identified by the Vocabulary Term bearer (i.e., "scheme": "bearer") for situations where bearer tokens are used independently of OAuth2. If the oauth2 scheme is specified it is not generally necessary to specify this scheme as well as it is implied. For format, the value jwt indicates conformance with [RFC7519], jws indicates conformance with [RFC7797], cwt indicates conformance with [RFC8392], and jwe indicates conformance with [RFC7516], with values for alg interpreted consistently with those standards. Other formats and algorithms for bearer tokens MAY be specified in vocabulary extensions.

Table 21 Vocabulary Terms in BearerSecurityScheme Level
Vocabulary term Description Assignment Type
authorization URI of the authorization server. optional anyURI
name Name for query, header, cookie, or uri parameters. optional string
alg Encoding, encryption, or digest algorithm. with default string (e.g., ES256, or ES512-256)
format Specifies format of security authentication information. with default string (e.g., jwt, cwt, jwe, or jws)
in Specifies the location of security authentication information. with default string (one of header, query, body, cookie, or auto)

Pre-shared key authentication security configuration identified by the Vocabulary Term psk (i.e., "scheme": "psk"). This is meant to identify that a standard is used for pre-shared keys such as TLS-PSK [RFC4279], and that the ciphersuite used for keys will be established during protocol negotiation.

Table 22 Vocabulary Terms in PSKSecurityScheme Level
Vocabulary term Description Assignment Type
identity Identifier providing information which can be used for selection or confirmation. optional string

OAuth 2.0 authentication security configuration for systems conformant with [RFC6749] and [RFC8252], identified by the Vocabulary Term oauth2 (i.e., "scheme": "oauth2").

Table 23 Vocabulary Terms in OAuth2SecurityScheme Level
Vocabulary term Description Assignment Type
authorization URI of the authorization server. optional anyURI
token URI of the token server. optional anyURI
refresh URI of the refresh server. optional anyURI
scopes Set of authorization scope identifiers provided as an array. These are provided in tokens returned by an authorization server and associated with forms in order to identify what resources a client may access and how. The values associated with a form SHOULD be chosen from those defined in an OAuth2SecurityScheme active on that form. optional string or Array of string
flow Authorization flow. mandatory string (e.g., code, or client)

For the code flow both authorization and token vocabulary terms MUST be included. For the client flow token vocabulary term MUST be included. For the client flow authorization vocabulary term MUST NOT be included. The mandatory elements for each flow are summarized in the following table:

Element code client
authorization mandatory omit
token mandatory mandatory
refresh optional optional

The present model provides a representation for (typed) Web links and Web forms exposed by a Thing. The Link class definition reflects a very common subset of the terms defined in Web Linking [RFC8288]. The defined terms can be used, e.g., to describe the relation to another Thing such as a Lamp Thing is controlled by a Switch Thing. The Form class corresponds to a newly introduced form of hypermedia control to manipulate the state of Things (and other Web resources).

A link can be viewed as a statement of the form "link context has a relation type resource at link target", where the optional target attributes may further describe the resource.

Table 24 Vocabulary Terms in Link Level
Vocabulary term Description Assignment Type
href Target IRI of a link or submission target of a form. mandatory anyURI
type Target attribute providing a hint indicating what the media type [RFC2046] of the result of dereferencing the link should be. optional string
rel A link relation type identifies the semantics of a link. optional string
anchor Overrides the link context (by default the Thing itself identified by its id) with the given URI or IRI. optional anyURI
sizes Target attribute that specifies one or more sizes for the referenced icon. Only applicable for relation type "icon". The value pattern follows {Height}x{Width} (e.g., "16x16", "16x16 32x32"). optional string
hreflang The hreflang attribute specifies the language of a linked document. The value of this must be a valid language tag [BCP47]. optional string or Array of string

Note: hreflang type

The hreflang attribute is allowed to be a string or array in this version of the spec. Depending on the result of [LINKSET-MEDIA-TYPES] the values of hrefLang can be restricted to array only.

Link relations can be used to describe relations such as to other Things (e.g., a Switch Thing controls a Lamp Thing), to a specific kind of Thing Models (e.g., a Thing Description is an instance of a specific Thing Model), or to further documentations information (e.g., device manual of a Thing). It is recommended to reuse existing and established Link Relation definitions from IANA.

In the following a best practice relation type table is introduced that is recommended to use within WoT Thing Description or Thing Model instances.

Table 25 Best practice relation type table
Value Occurrence Explanation Source of value origin
icon 0..* Imports an icon associated to the Thing (e.g., for UI purposes). IANA Link Relation
service-doc 0..* Relation to a resource that provide (human-readable) documentation or descriptions. IANA Link Relation
alternate 0..* Point to alternative representation of the Thing (i.e. RDF-Turtle, human-readable HTML document, ...). IANA Link Relation
type 0..1 Indicate that the Thing is an instance of the target resource such as to a Thing Model. IANA Link Relation
tm:extends 0..1 Extends an existing definition of the target resource such as a Thing Model. Only applicable for Thing Model definitions. W3C WoT Thing Model
tm:submodel 0..* Used to compose one or multiple Thing Models. Only applicable for Thing Model definitions. W3C WoT Thing Model
manifest 0..* Point to the web app manifest of a web application which provides, e.g., a user interface with which a user can interact with the Thing (also see [APPMANIFEST]). IANA Link Relation
proxy-to 0..* Target resource provide the address of a proxy. Additional security metadata can be provided using the proxy field in a SecurityScheme. W3C WoT Security and WoT Binding Template
collection 0..1 Points to a collections of Things. IANA Link Relation
item 0..* Points to a Thing that is member of the current Thing collections. IANA Link Relation
predecessor-version 0..1 Points to a previous Thing Description or Thing Model version. IANA Link Relation
controlledBy 0..* Refers to a Thing that controls the context Thing. W3C Thing Description

A form can be viewed as a statement of "To perform an operation type operation on form context, make a request method request to submission target" where the optional form fields may further describe the required request. In Thing Descriptions, the form context is the surrounding Object, such as Properties, Actions, and Events or the Thing itself for meta-interactions.

Table 26 Vocabulary Terms in Form Level
Vocabulary term Description Assignment Type
href Target IRI of a link or submission target of a form. mandatory anyURI
contentType Assign a content type based on a media type (e.g., text/plain) and potential parameters (e.g., charset=utf-8) for the media type [RFC2046]. with default string
contentCoding Content coding values indicate an encoding transformation that has been or can be applied to a representation. Content codings are primarily used to allow a representation to be compressed or otherwise usefully transformed without losing the identity of its underlying media type and without loss of information. Examples of content coding include "gzip", "deflate", etc. . optional string
security Set of security definition names, chosen from those defined in securityDefinitions. These must all be satisfied for access to resources. optional string or Array of string
scopes Set of authorization scope identifiers provided as an array. These are provided in tokens returned by an authorization server and associated with forms in order to identify what resources a client may access and how. The values associated with a form SHOULD be chosen from those defined in an OAuth2SecurityScheme active on that form. optional string or Array of string
response This optional term can be used if, e.g., the output communication metadata differ from input metadata (e.g., output contentType differ from the input contentType). The response name contains metadata that is only valid for the primary response messages. optional ExpectedResponse
additionalResponses This optional term can be used if additional expected responses are possible, e.g. for error reporting. Each additional response needs to be distinguished from others in some way (for example, by specifying a protocol-specific error code), and may also have its own data schema. optional Array of AdditionalExpectedResponse
subprotocol Indicates the exact mechanism by which an interaction will be accomplished for a given protocol when there are multiple options. For example, for HTTP and Events, it indicates which of several available mechanisms should be used for asynchronous notifications such as long polling (longpoll), WebSub [websub] (websub), Server-Sent Events (sse) [html] (also known as EventSource). Please note that there is no restriction on the subprotocol selection and other mechanisms can also be announced by this subprotocol term. optional string (e.g., longpoll, websub, or sse)
op Indicates the semantic intention of performing the operation(s) described by the form. For example, the Property interaction allows get and set operations. The protocol binding may contain a form for the get operation and a different form for the set operation. The op attribute indicates which form is for which and allows the client to select the correct form for the operation required. op can be assigned one or more interaction verb(s) each representing a semantic intention of an operation. with default string or Array of string (one of readproperty, writeproperty, observeproperty, unobserveproperty, invokeaction, queryaction, cancelaction, subscribeevent, unsubscribeevent, readallproperties, writeallproperties, readmultipleproperties, writemultipleproperties, observeallproperties, unobserveallproperties, subscribeallevents, unsubscribeallevents, or queryallactions)

Possible values for the contentCoding property can be found, e.g., in the IANA HTTP content coding registry.

The list of possible operation types of a form is fixed. As of this version of the specification, it only includes the well-known types necessary to implement the WoT interaction model described in [wot-architecture11]. Future versions of the standard may extend this list but operations types MUST be restricted to the values in the table below.

Table 27 Well-known operation types
Operation Type Description
readproperty Identifies the read operation on Property Affordances to retrieve the corresponding data.
writeproperty Identifies the write operation on Property Affordances to update the corresponding data.
observeproperty Identifies the observe operation on Property Affordances to be notified with the new data when the Property is updated.
unobserveproperty Identifies the unobserve operation on Property Affordances to stop the corresponding notifications.
invokeaction Identifies the invoke operation on Action Affordances to perform the corresponding action.
queryaction Identifies the querying operation on Action Affordances to get the status of the corresponding action.
cancelaction Identifies the cancel operation on Action Affordances to cancel the ongoing corresponding action.
subscribeevent Identifies the subscribe operation on Event Affordances to be notified by the Thing when the event occurs.
unsubscribeevent Identifies the unsubscribe operation on Event Affordances to stop the corresponding notifications.
readallproperties Identifies the readallproperties operation on a Thing to retrieve the data of all Properties in a single interaction.
writeallproperties Identifies the writeallproperties operation on a Thing to update the data of all writable Properties in a single interaction.
readmultipleproperties Identifies the readmultipleproperties operation on a Thing to retrieve the data of selected Properties in a single interaction.
writemultipleproperties Identifies the writemultipleproperties operation on a Thing to update the data of selected writable Properties in a single interaction.
observeallproperties Identifies the observeallproperties operation on Properties to be notified with new data when any Property is updated.
unobserveallproperties Identifies the unobserveallproperties operation on Properties to stop notifications from all Properties in a single interaction.
queryallactions Identifies the queryallactions operation on a Thing to get the status of all Actions in a single interaction.
subscribeallevents Identifies the subscribeallevents operation on Events to subscribe to notifications from all Events in a single interaction.
unsubscribeallevents Identifies the unsubscribeallevents operation on Events to unsubscribe from notifications from all Events in a single interaction.

A Thing Description of a WoT producer may have multiple forms entries with, e.g., different protocol and/or content types declarations that a Consumer could possibly support. In that case the Consumer may choose any form entry that works (e.g., the protocol and content type is supported) for them. When one form is chosen, it is expected that the Consumer will continue to use it as long as possible for every new interaction with the WoT producer.

This section is non-normative.

Protocols that can be used with TDs follow request-response or eventing mechanisms. The Data Schema of an affordance generally correlates with the op keywords used in forms. The table below informatively summarizes the available data schema related terms with the op keywords.

  • Consumer to Thing applies for messages sent by the Consumer to the Thing, such as the value for writing a property.
  • Thing to Consumer applies for messages sent by the Thing to the Consumer, such as the value of a property value as the result of reading a property.
  • In case that there is no correlation with the data schema and the operation, it implies that no payload is required for executing the operation or no payload is expected as a result of the operation.
Table 28 Mapping op Values to Data Schemas
Operation Type Consumer to Thing DataSchema Correlation Thing to Consumer DataSchema Correlation
readproperty No correlation. All fields in the Property Affordance without "writeOnly":true.
writeproperty All fields in the Property Affordance without "readOnly":true. No correlation. additionalResponses can be used in the form level.
observeproperty No correlation. All fields in the Property Affordance without "writeOnly":true.
unobserveproperty No correlation. No correlation.
invokeaction Value of the input key. Value of the output key.
queryaction No correlation. No correlation. additionalResponses can be used in the form level.
cancelaction No correlation. No correlation. additionalResponses can be used in the form level.
subscribeevent Value of the subscription key with all fields without "readOnly":true Value of the subscription key with all fields without "writeOnly":true
unsubscribeevent Value of the subscription key with all fields without "readOnly":true Value of the subscription key with all fields without "writeOnly":true

Note: writeproperty and observeproperty relationship

Writing to a property does not necessarily mean that a new value will be sent to the Consumer observing the property. It depends on the protocol and implementation.

Note: Further Data Schemas mappings

Further specification of how to map operations to data schemas, as well as mapping meta operations such as readallproperties can be found in the respective protocol specification of the [WOT-BINDING-TEMPLATES].

The optional response name-value pair can be used to provide metadata for the expected response message. With the core vocabulary, it only includes content type information, but TD Context Extensions could be applied. If no response name-value pair is provided, it MUST be assumed that the content type of the response is equal to the content type assigned to the Form instance. Note that contentType within an ExpectedResponse Class does not have a Default Value. For instance, if the value of the content type of the form is application/xml the assumed value of the content type of the response will be also application/xml.

In some cases additional responses might be possible. One example of this is error responses but in some cases there might also be additional successful responses. In this case, the response name-value pair is still used for the primary response but additionalResponses may also be provided, whose value is an array of AdditionalExpectedResponse objects. Each additional response must be distinguished in some way from the primary response, either by contentType or by protocol-specific settings such as error code header values. Each additional response may also have a data schema which can differ from the normal output data schema for the interaction.

In some use cases, input and output data might be represented in a different form, for instance an Action that accepts JSON, but returns an image. In such a case, the optional response name-value pair can describe the content type of the expected response. If the content type of the expected response differs from the content type of the form, the Form instance MUST include a name-value pair with the name response. For instance, an ActionAffordance could only accept application/json for its input data, while it will respond with an image/jpeg content type for its output data. In that case the content types differ and the response name-value pair has to be used to provide response content type (image/jpeg) information to the Consumer.

Similar considerations apply to additional responses, although in this case the contentType is optional if it is the same as the input content Type (e.g. JSON). If the content type of an additional expected response differs from the content type of the form, the Form instance MUST include an entry in the array associated with the name additionalResponses that includes a value for the name contentType. If the data schema of an additional expected response differs from the output data schema of the interaction, the Form instance MUST include an entry in the array associated with the name additionalResponses that includes a value for the name schema.

The different cases on the variation of request and response are explained above. The tables at C. contentType usage in Thing Descriptions summarize these cases in a concise manner.

Communication metadata describing the expected response message for the primary response.

Table 29 Vocabulary Terms in ExpectedResponse Level
Vocabulary term Description Assignment Type
contentType Assign a content type based on a media type (e.g., text/plain) and potential parameters (e.g., charset=utf-8) for the media type [RFC2046]. mandatory string

Communication metadata describing the expected response message for additional responses.

Table 30 Vocabulary Terms in AdditionalExpectedResponse Level
Vocabulary term Description Assignment Type
success Signals if an additional response should not be considered an error. with default boolean
contentType Assign a content type based on a media type (e.g., text/plain) and potential parameters (e.g., charset=utf-8) for the media type [RFC2046]. with default string
schema Used to define the output data schema for an additional response if it differs from the default output data schema. Rather than a DataSchema object, the name of a previous definition given in a schemaDefinitions map must be used. optional string

When assignments in a TD are missing, a TD Processor MUST follow the Default Value assignments expressed in the table of Default Value Definitions.

The following table gives all Default Values defined in the TD Information Model.

Table 31 Default values of vocabulary terms that are used when the terms are not present in a TD
Class Vocabulary Term Default Value Comment
PropertyAffordance readOnly false The default value for this vocabulary term applies only to the PropertyAffordance level definition. In other contexts, such as DataSchema definitions, the vocabulary term is optional.
PropertyAffordance writeOnly false The default value for this vocabulary term applies only to the PropertyAffordance level definition. In other contexts, such as DataSchema definitions, the vocabulary term is optional.
PropertyAffordance observable false
ActionAffordance safe false
ActionAffordance idempotent false
AdditionalExpectedResponse success false
AdditionalExpectedResponse contentType value of the contentType of the Form element it belongs to.
Form contentType application/json
Form op Array of string with the elements readproperty and writeproperty when readOnly and writeOnly are set to false or Array of string with the element readproperty when readOnly is set to true or Array of string with the element writeproperty when writeOnly is set to true.
If defined within an instance of PropertyAffordance
Form op invokeaction If defined within an instance of ActionAffordance
Form op Array of string with the elements subscribeevent and unsubscribeevent If defined within an instance of EventAffordance
BasicSecurityScheme in header
DigestSecurityScheme in header
DigestSecurityScheme qop auth
APIKeySecurityScheme in query
BearerSecurityScheme in header
BearerSecurityScheme alg ES256
BearerSecurityScheme format jwt

WoT Thing Descriptions represent Things and are modeled and structured based on 5. TD Information Model. This section defines a JSON-based representation format for Things, a serialization of instances of the Class Thing defined by the TD Information Model.

A TD Processor MUST be able to serialize Thing Descriptions into the JSON format [RFC8259] and/or deserialize Thing Descriptions from that format, according to the rules noted in 6.1 Mapping to JSON Types and 6.3 Information Model Serialization.

The JSON serialization of the TD Information Model is aligned with the syntax of JSON-LD 1.1 [json-ld11] in order to streamline semantic evaluation. Hence, the TD representation format can be processed either as raw JSON or with a JSON-LD 1.1 processor (for details about semantic processing, please refer to D. JSON-LD Context Usage and the documentation under the namespace IRIs, e.g., https://www.w3.org/2019/wot/td).

In order to support interoperable internationalization, TDs MUST be serialized according to the requirements defined in Section 8.1 of RFC8259 [RFC8259] for open ecosystems. In summary, this requires the following:

  • TDs MUST be encoded using UTF-8 [RFC3629].
  • Implementations MUST NOT add a byte order mark (U+FEFF) to the beginning of a TD document.
  • TD Processors MAY ignore the presence of a byte order mark rather than treating it as an error.

The TD Information Model is constructed, so that there is an easy mapping between model Objects and JSON types. Every Class instances maps to a JSON object, where each name-value pair of the Class instance is a member of the JSON object.

Every Simple Type mentioned in 5.3 Class Definitions (i.e., string, anyURI, dateTime, integer, unsignedInt, double, and boolean) maps to a primitive JSON type (string, number, boolean), as per the rules listed below. These rules apply to values in name-value pairs:

  • Values that are of type string or anyURI MUST be serialized as JSON strings.
  • Values that are of type dateTime MUST be serialized as JSON strings following the "date-time" format specified by [RFC3339]. Examples would include 2019-05-24T13:12:45Z and 2015-07-11T09:32:26+08:00. Values that are of type dateTime SHOULD use the literal Z representing the UTC time zone instead of an offset.
  • Values that are of type integer or unsignedInt MUST be serialized as JSON numbers without a fraction or exponent part.
  • Values that are of type double MUST be serialized as JSON number.
  • Values that are of type boolean MUST be serialized as JSON boolean.

Every complex type of the TD Information Model (i.e., Arrays, Maps, and Class instances) maps to a structured JSON type (array and object), as per the rules listed below:

  • A value of type Array MUST be serialized as JSON array, with each value of the name-value pairs as element of the JSON array ordered by the numeric name of the pair.
  • A value of type Map MUST be serialized as a JSON object, with each name-value pair as member of the JSON object.
  • A Class instance MUST be serialized as a JSON object, following the detailed rules given individually in 6.3 Information Model Serialization.

A Thing Description serialization may omit Vocabulary Term for which Default Values are defined, as listed in the table given in 5.4 Default Value Definitions.

The following example shows the TD instance from Example 1 with a checkbox to also include the members with Default Values (=checkbox checked). These members can be omitted (=checkbox unchecked) to simplify the TD serialization. Note that a TD Processor interprets these omitted members identically as if they were explicitly present with a given Default Value.

Please note that, depending on the Protocol Binding used, additional protocol-specific Vocabulary Terms may apply. They may also have associated Default Values, and hence can also be omitted as explained in this subsection. Further information can be found in 8.3 Protocol Bindings.

A Thing Description is a data structure rooted at an Object of type Thing. In turn, a JSON serialization of the Thing Description is a JSON object, which is the root of a syntax tree constructed from the TD Information Model.

The root element of a TD Serialization MUST be a JSON object that includes a member with the name @context and a value of type string or array that equals or respectively contains https://www.w3.org/2022/wot/td/v1.1.

In general, this URI is used to identify the TD representation format version defined by this specification. For JSON-LD processing [json-ld11], this URI specifies the Thing Description context file. An @context of type array indicates TD Context Extensions (see 7. TD Context Extensions for details).

Example 5

{
    "@context": "https://www.w3.org/2022/wot/td/v1.1",
    // ...
}

All name-value pairs of an instance of Thing, where the name is a Vocabulary Term in the Signature of Thing, MUST be serialized as JSON members of the root object.

A TD snippet for a serialized root object including all mandatory and optional members is given below:

Example 6

: Sample of Thing serializations

{
    "@context": "https://www.w3.org/2022/wot/td/v1.1",
    "@type": "Thing",
    "id": "urn:uuid:1b37933b-3212-4dad-9c2c-74c6042c3e2b",
    "title": "MyThing",
    "titles": {/*...*/},
    "description": "Human readable information.",
    "descriptions": {/*...*/},
    "support": "mailto:support@example.com",
    "version": {/*...*/},
    "created": "2018-11-14T19:10:23.824Z",
    "modified": "2019-06-01T09:12:43.124Z",
    "securityDefinitions": {/*...*/},
    "security": /*...*/,
    "base": "https://servient.example.com/",
    "properties": {/*...*/},
    "actions": {/*...*/},
    "events": {/*...*/},
    "links": [...],
    "forms": [...]
}

All values assigned to version, securityDefinitions, descriptions, schemaDefinitions, uriVariables, properties, actions, and events in an instance of the Class Thing MUST be serialized as JSON objects.

All values assigned to links, and forms in an instance of the Class Thing MUST be serialized as JSON arrays containing JSON objects as defined in 6.3.8 links and 6.3.9 forms, respectively.

The value assigned to security in an instance of Class Thing MUST be serialized as JSON string or as JSON array whose elements are JSON strings.

JSON members named title and description are used within a TD document to provide human-readable metadata. They can be used as comments for developers inspecting a TD document or as display texts for user interface.

As defined in 5.3.1.1 Thing, the base text direction used to display human-readable metadata can either be estimated using heuristics such as the first-strong rule or inferred from language information. In TD documents the default language is defined by a value assigned to @language in the @context, and this, along with a script subtag if necessary, can be used to determine a base text direction. However, when interpreting human-readable text, each human-readable string value MUST be processed independently. In other words, a TD Processor cannot carry forward changes in direction from one string to another, or infer direction for one string from another one elsewhere in the TD.

A TD snippet using title and description is shown below. The default language is set to en through the definition of the @language member within a JSON object in the @context array.

Example 7

{
    "@context": [
        "https://www.w3.org/2022/wot/td/v1.1",
        { "@language": "en" }
    ],
    "title": "MyThing",
    "description": "Human readable information.",
    // ...
    "properties": {
        "on": {
            "title": "On/Off",
            "type": "boolean",
            "forms": [...]
        },
        "status": {
            "title": "Status",
            "type": "object",
            // ...
            "forms": [...]
        }
    },
    // ...
}

Strings on the Web [STRING-META] recommends the use of metadata to determine the base direction of string values. Given that the Thing Description format is based on JSON-LD 1.1 [json-ld11], @direction with the string values "ltr", "rtl" and null value null MAY be used inside the @context to indicate the default text direction for the human readable strings in the entire TD document. When metadata such as @direction is not present, TD Consumers SHOULD use first-strong detection as a fallback. For the MultiLanguage Map, TD Consumers MAY infer the base direction from the language tag of the individual strings. The example below illustrates the use of the @direction term. See [json-ld11] and [string-meta] for more detailed information.

Example 8

{
     "@context": [
         "https://www.w3.org/2022/wot/td/v1.1",
         {
           "@language": "ar-EG",
           "@direction": "rtl"
         }
     ],
     "title": "شيء يخصني يقيس درجة الحرارة",
     "description": "شيء يقيس درجة الحرارة و يظهر حالته",
     // ...
     "properties": {
         "temp": {
             "title": "درجة الحرارة",
             "type": "boolean",
             "forms": [...]
         },
         "status": {
             "title": "حالة",
             "type": "object",
             // ...
             "forms": [...]
         }
     },
     // ...
 }

The JSON members named titles and descriptions are used within the TD document to provide human-readable metadata in multiple languages within a single TD document. All name-value pairs of a MultiLanguage Map MUST be serialized as members of a JSON object, where the name is a valid language tag as defined by [BCP47] (also see W3C I18N Glossary) and the value is a human-readable string in the language indicated by the tag. See 5.3.1.7 MultiLanguage for details. All MultiLanguage object within a TD document SHOULD contain the same set of language members.

A TD snippet using titles and descriptions at different levels is given below:

Example 9

{
    "@context": "https://www.w3.org/2022/wot/td/v1.1",
    "title": "MyThing",
    "titles": {
        "en": "MyThing",
        "de": "MeinDing",
        "ja": "私の物",
        "zh-Hans": "我的东西",
        "zh-Hant": "我的東西"
    },
    "descriptions": {
        "en": "Human readable information.",
        "de": "Menschenlesbare Informationen.",
        "ja": "人間が読むことができる情報",
        "zh-Hans": "人们可阅读的信息",
        "zh-Hant": "人們可閱讀的資訊"
    },
    // ...
    "properties": {
        "on": {
            "titles": {
                "en": "On/Off",
                "de": "An/Aus",
                "ja": "オンオフ",
                "zh-Hans": "开关",
                "zh-Hant": "開關" },
            "type": "boolean",
            "forms": [...]
        },
        "status": {
            "titles": {
                "en": "Status",
                "de": "Zustand",
                "ja": "状態",
                "zh-Hans": "状态",
                "zh-Hant": "狀態" },
            "type": "object",
            // ...
            "forms": [...]
        }
    },
    // ...
}

TD instances may also combine the use of title and description with titles and descriptions. When title and titles or description and descriptions are present within the same JSON object, the values of title and description MAY be seen as the default text. When title and titles or description and descriptions are present in a TD document, each title and description member SHOULD have a corresponding titles and descriptions member, respectively. The language of the default text is indicated by the default language, which is usually set by the creator of the Thing Description instance.

Example 10

{
    "@context": [
        "https://www.w3.org/2022/wot/td/v1.1",
        { "@language": "de" }
    ],
    "title": "MeinDing",
    "titles": {
        "en": "MyThing",
        "de": "MeinDing",
        "ja": "私の物",
        "zh-Hans": "我的东西",
        "zh-Hant": "我的東西"
    },
    "description": "Menschenlesbare Informationen.",
    "descriptions": {
        "en": "Human readable information.",
        "de": "Menschenlesbare Informationen.",
        "ja": "人間が読むことができる情報",
        "zh-Hans": "人们可阅读的信息",
        "zh-Hant": "人們可閱讀的資訊"
    },
    // ...
    "properties": {
        "on": {
            "title": "An/Aus",
            "titles": {
                "en": "On/Off",
                "de": "An/Aus",
                "ja": "オンオフ",
                "zh-Hans": "开关",
                "zh-Hant": "開關" },
            "type": "boolean",
            "forms": [...]
        },
        "status": {
            "title": "Zustand",
            "titles": {
                "en": "Status",
                "de": "Zustand",
                "ja": "状態",
                "zh-Hans": "状态",
                "zh-Hant": "狀態" },
            "type": "object",
            // ...
            "forms": [...]
        }
    },
    // ...
}

Another possibility to set the default language is through a language negotiation mechanism, such as the Accept-Language header field of HTTP. In cases where the default language has been negotiated, an @language member MUST be present to indicate the result of the negotiation and the corresponding default language of the returned content. When the default language has been negotiated successfully, TD documents SHOULD include the appropriate matching values for the members title and description in preference to MultiLanguage objects in titles and descriptions members. Note however that Things MAY choose to not support such dynamically-generated TDs nor to support language negotiation (e.g., because of resource constraints).

There is no guarantee that strings in TDs will be displayed in an HTML rendering context. In fact, to mitigate the XSS security risk described in 10.5 Script Injection, HTML tags embedded in strings sourced from TDs should be sanitized (and so not interpreted as HTML) in applications embedding these strings in web pages or web applications. Therefore HTML embedded in strings is not an appropriate mechanism for specifying text rendering direction.

All name-value pairs of an instance of VersionInfo, where the name is a Vocabulary Term included in the Signature of VersionInfo, MUST be serialized as JSON members with the Vocabulary Term as name.

A TD snippet of a version information object is given below:

Example 11

{
    // ...
    "version": { "instance": "1.2.1" },
    // ...
}

The version member is intended as container for additional application- and/or device-specific version information based on TD Context Extensions. See 7.1 Semantic Annotations for details.

In a Thing instance, the value assigned to securityDefinitions is a Map of instances of SecurityScheme. All name-value pairs of a Map of SecurityScheme instances MUST be serialized as members of the JSON object that results from serializing the Map; the name of a pair MUST be serialized as a JSON string and the value of the pair, an instance of SecurityScheme, MUST be serialized as a JSON object.

All name-value pairs of an instance of one of the Subclasses of SecurityScheme, where the name is a Vocabulary Term included in the Signature of that Subclass or in the Signature of SecurityScheme, MUST be serialized as members of the JSON object that results from serializing the SecurityScheme Subclass's instance, with the Vocabulary Term as name.

The following TD snippet shows a simple security configuration specifying basic username/password authentication in the header. The value given for in is actually the Default Value (header) and could be omitted. A named security configuration (basic_sc) is given in the securityDefinitions map. In this example, that definition is activated by including its JSON name in the security member.

Example 12

{
    // ...
    "securityDefinitions": {
        "basic_sc": {
            "scheme": "basic",
            "in": "header"
        }
    },
    "security": "basic_sc",
    // ...
}

Security configuration in the TD is mandatory. At least one security definition MUST be activated through the security member at the Thing level (i.e., in the TD root object). This configuration can be seen as the default security mechanism required to interact with the Thing. Security definitions MAY also be activated at the level of the form elements by including a security member in form objects, which overrides (i.e., completely replace) all definitions activated at the Thing level.

The nosec security scheme is provided for the case that no security is needed. The minimal security configuration for a Thing is activation of the nosec security scheme at the Thing level, as shown in the following example:

Example 13

{
    "@context": "https://www.w3.org/2022/wot/td/v1.1",
    "id": "urn:uuid:e9ecb6ad-cd4c-481b-96ce-5b4c57ddb844",
    "title": "MyThing",
    "description": "Human readable information.",
    "support": "https://servient.example.com/contact",
    "securityDefinitions": { "nosec_sc": { "scheme": "nosec" }},
    "security": "nosec_sc",
    "properties": {/*...*/},
    "actions": {/*...*/},
    "events": {/*...*/},
    "links": [/*...*/]
}

To give a more complex example, suppose we have a Thing where all Interaction Affordances require basic authentication except for one, for which no authentication is required. For the status Property and the toggle Action, basic authentication is required and defined at the Thing level. For the overheating Event, however, no authentication is required, and hence the security configuration is overridden at the form level.

Example 14

{
    // ...
    "securityDefinitions": {
        "basic_sc": {"scheme": "basic"},
        "nosec_sc": {"scheme": "nosec"}
    },
    "security": "basic_sc",
    // ...
    "properties": {
        "status": {
            // ...
            "forms": [{
                "href": "https://mylamp.example.com/status"
            }]
        }
    },
    "actions": {
        "toggle": {
            // ...
            "forms": [{
                "href": "https://mylamp.example.com/toggle"
            }]
        }
    },
    "events": {
        "overheating": {
            // ...
            "forms": [{
                "href": "https://mylamp.example.com/oh",
                "security": "nosec_sc"
            }]
        }
    }
}

TDs can specify a combination of security schemes as well. Below is a TD snippet showing digest authentication on a proxy combined with bearer token authentication on the Thing. In the digest scheme, the Default Value of in (i.e., header) is omitted, but still applies. Note that the corresponding private security configuration such as username/password and tokens need to be configured in the Consumer to interact successfully. When activating multiple security definitions, the security member becomes an array.

Example 15

{
    // ...
    "securityDefinitions": {
        "proxy_sc": {
            "scheme": "digest",
            "proxy": "https://portal.example.com/"
        },
        "bearer_sc": {
            "scheme": "bearer",
            "in": "header",
            "format": "jwt",
            "alg": "ES256",
            "authorization": "https://servient.example.com:8443/"
        }
    },
    "security": ["proxy_sc", "bearer_sc"],
    // ...
}

However, the use of an array with multiple elements to combine security schemes in a security element is now deprecated, instead a ComboSecurityScheme SHOULD be used. In the following example, which is exactly equivalent to the one above, this is demonstrated:

Example 16

{
    // ...
    "securityDefinitions": {
        "proxy_sc": {
            "scheme": "digest",
            "proxy": "https://portal.example.com/"
        },
        "bearer_sc": {
            "scheme": "bearer",
            "in": "header",
            "format": "jwt",
            "alg": "ES256",
            "authorization": "https://servient.example.com:8443/"
        },
        "combo_sc": {
            "scheme": "combo",
            "allOf": ["proxy_sc", "bearer_sc"]
        }
    },
    "security": "combo_sc",
    // ...
}

Security configurations can also be specified for different forms within the same Interaction Affordance. This may be required for devices that support multiple protocols, for example HTTP and CoAP [RFC7252], which support different security mechanisms. This is also useful when alternative authentication mechanisms are allowed. Here is a TD snippet demonstrating three possible ways to activate a Property affordance: via HTTPS with basic authentication, with digest authentication, with bearer token authentication. In other words, the use of different security configurations within multiple forms provides a way to combine security mechanisms in an "OR" fashion. In contrast, putting multiple security configurations in the same security member combines them in an "AND" fashion, since in that case they would all need to be satisfied to allow activation of the Interaction Affordance. Note that activating one (default) configuration at the Thing level is still mandatory.

Example 17

{
    // ...
    "securityDefinitions": {
        "basic_sc": { "scheme": "basic" },
        "digest_sc": { "scheme": "digest" },
        "bearer_sc": { "scheme": "bearer" }
    },
    "security": "basic_sc",
    // ...
    "properties": {
        "status": {
            // ...
            "forms": [{
                "href": "https://mylamp.example.com/status"
            }, {
                "href": "https://mylamp.example.com/status",
                "security": "digest_sc"
            }, {
                "href": "https://mylamp.example.com/status",
                "security": "bearer_sc"
            }]
        }
    },
    // ...
}

To avoid redundancy in this case, e.g. repeating the details of the form elements, a ComboSecurityScheme with oneOf can be used instead.

Example 18

{
    // ...
    "securityDefinitions": {
        "basic_sc": { "scheme": "basic" },
        "digest_sc": { "scheme": "digest" },
        "bearer_sc": { "scheme": "bearer" },
        "combo_sc": {
            "scheme": "combo",
            "oneOf": [ "basic_sc", "digest_sc", "bearer_sc" ]
        }
    },
    "security": "combo_sc",
    // ...
    "properties": {
        "status": {
            // ...
            "forms": [{
                "href": "https://mylamp.example.com/status"
            }]
        }
    },
    // ...
}

As another more complex example, OAuth 2.0 makes use of scopes. These are identifiers that may appear in tokens and must match with corresponding identifiers in a resource to allow access to that resource (or Interaction Affordance in the case of W3C WoT). For example, in the following, the status Property can be read by Consumers using bearer tokens containing the scope limited, but the configure Action can only be invoked with a token containing the special scope. Scopes are not identical to roles, but are often associated with them; for example, perhaps only those in an administrative role are authorized to perform "special" interactions. Tokens can have more than one scope and are issued by dedicated web services to users. In this example, an administrator could be issued tokens with both the limited and special scopes, while ordinary users could be provided with tokens with the limited scope.

Example 19

{
    // ...
    "securityDefinitions": {
        "oauth2_sc": {
            "scheme": "oauth2",
            "flow": "client",
            "token": "https://example.com/token",
            "scopes": ["limited", "special"]
        }
    },
    "security": "oauth2_sc",
    // ...
    "properties": {
        "status": {
            // ...
            "forms": [{
                "href": "https://scopes.example.com/status",
                "scopes": ["limited"]
            }]
        }
    },
    "actions": {
        "configure": {
            // ...
            "forms": [{
                "href": "https://scopes.example.com/configure",
                "scopes": ["special"]
            }]
        }
    },
    // ...
}

A Thing can require an onboarding process that results in the Consumer requiring an API key to interact with the Thing. This API key can be included in the request to the Thing in different ways as the API key scheme specifies. Below is an example of how it can be used as a URI template where the API key should be replaced in the URI by the Consumer when sending an HTTPS request.

Example 20

{
    // ...
    "securityDefinitions": {
        "apikey_key": {
            "scheme": "apikey",
            "in": "uri",
            "name": "adminKey"
        }
    },
    "security": "apikey_key",
    "properties": {
        "status": {
            // ...
            "forms": [{
                "href": "https://example.com/{adminKey}/status",
                // ...
            }]
        }
    },
    // ...
}

To give another example of the use of the ComboSecurityScheme in addition to the use of URI templates example shown above, suppose there is a security scheme where a client ID and a "secret" key provided by a cloud service provider must both be embedded in the URL. Technically, only the key is actually secret and must be handled out-of-band, and the client ID, which is not secret, could be embedded in the TD. However, if the client ID cannot be easily rotated we may want to avoid embedding it in the TD to enhance privacy. In this case we can combine two instances of APIKeySecurityScheme, both using the uri value for the in location specifier, to declare two URI variables. These can then (in fact, they must) be used in the href in a Form where the security scheme is active. An example follows:

Example 21

{
    // ...
    "securityDefinitions": {
        "apikey_key": {
            "scheme": "apikey",
            "in": "uri",
            "name": "secKey"
        },
        "apikey_id": {
            "scheme": "apikey",
            "in": "uri",
            "name": "secClientID"
        },
        "apikey_combo": {
            "scheme": "combo",
            "allOf": ["apikey_key","apikey_id"]
        }
    },
    "security": "apikey_combo",
    // ...
    "properties": {
        "status": {
            // ...
            "forms": [{
                "href": "https://example.com/{secClientID}/status/{secKey}",
                // ...
            }]
        }
    },
    // ...
}

While not shown in this example, it is legal to declare additional URI template variables using uriVariables and include them in the same URI template, although the names cannot conflict with those declared in security schemes. Using a specific prefix as in the above example for URI variables declared in security schemes can make it easier to avoid name conflicts.

API Key in Body: Security parameters might also be included along with the payload in some systems. For example, suppose a system requires every payload to be a JSON object including a member named auth whose value is an object containing a member called key containing an access key. Depending on the interaction, however, other elements of the JSON object might vary. This situation can be dealt with using the body security information location. Note that for this location, the name parameter is actually a JSON pointer evaluated relative to the root of the DataSchema for each interaction it is bound with, which allows it to be used with payloads that vary in other respects. As an example, here is a light that has a property to set its brightness and color and two separate actions to turn it on and off. Although the JSON payloads are different for these actions the /auth/key element occurs in the same relative location so single JSON pointer can be used. Note: if the security key occurs in different inconsistent locations, it will be necessary to use multiple security scheme definitions.

Example 22

{
    // ...
    "securityDefinitions": {
        "apikey_body": {
            "scheme": "apikey",
            "in": "body",
            "name": "/auth/key"
        }
    },
    "security": "apikey_body",
    // ...
    "properties": {
        "color": {
            // ...
            "type": "object",
            "properties": {
                "brightness": {
                    "type": "number",
                    // ...
                },
                "rgb": {
                    "type": "array",
                    // ...
                },
                "auth": {
                    "type": "object",
                    "properties": {
                        "key": {
                           "type": "string"
                        }
                    },
                    "required": ["key"]
                }
            },
            "required": ["brightness", "rgb", "auth"],
            "forms": [{
                "href": "https://example.com/color",
                // ...
            }]
        }
    },
    "action": {
        "on": {
            // ...
            "input": {
                "auth": {
                    "type": "object",
                    "properties": {
                        "key": {
                           "type": "string"
                        }
                    },
                    "required": ["key"]
                }
            },
            "required": ["auth"],
            "forms": [{
                "href": "https://example.com/on",
                // ...
            }]
        },
        "off": {
            // ...
            "input": {
                "auth": {
                    "type": "object",
                    "properties": {
                        "key": {
                           "type": "string"
                        }
                    },
                    "required": ["key"]
                }
            },
            "required": ["auth"],
            "forms": [{
                "href": "https://example.com/off",
                // ...
            }]
        }
    },
    // ...
}
However, it is rather annoying and redundant to add the security information to every data schema. It is possible to simplify this example by using the feature that the location referenced by a JSON pointer in a body location will be automatically inserted if it does not exist. In this case the above example can be simplified to the following. Note that in fact a data schema will effectively be created for the actions on and off to hold just the security information.

Example 23

{
    // ...
    "securityDefinitions": {
        "apikey_body": {
            "scheme": "apikey",
            "in": "body",
            "name": "/auth/key"
        }
    },
    "security": "apikey_body",
    // ...
    "properties": {
        "color": {
            // ...
            "type": "object",
            "properties": {
                "brightness": {
                    "type": "number",
                    // ...
                },
                "rgb": {
                    "type": "array",
                    // ...
                }
            },
            "required": ["brightness", "rgb"],
            "forms": [{
                "href": "https://example.com/color",
                // ...
            }]
        }
    },
    "action": {
        "on": {
            // ...
            "required": ["auth"],
            "forms": [{
                "href": "https://example.com/on",
                // ...
            }]
        },
        "off": {
            // ...
            "forms": [{
                "href": "https://example.com/off",
                // ...
            }]
        }
    },
    // ...
}

The value assigned to properties in a Thing instance is a Map of instances of PropertyAffordance. All name-value pairs of a Map of PropertyAffordance instances MUST be serialized as members of the JSON object that results from serializing the Map; the name of a pair MUST be serialized as a JSON string and the value of the pair, an instance of PropertyAffordance, MUST be serialized as a JSON object.

All name-value pairs of an instance of PropertyAffordance, where the name is a Vocabulary Term included in (one of) the Signatures of PropertyAffordance, InteractionAffordance, or DataSchema, MUST be serialized as members of the JSON object that results from serializing the PropertyAffordance instance, with the Vocabulary Term as name. See 6.3.10 Data Schemas for details on serializing DataSchema instances.

The value assigned to forms in an instance of PropertyAffordance MUST be serialized as a JSON array containing one or more JSON object serializations as defined in 6.3.9 forms.

A snippet for two Property affordances is given below:

In a Thing instance, the value assigned to actions is a Map of instances of ActionAffordance. All name-value pairs of a Map of ActionAffordance instances MUST be serialized as members of the JSON object that results from serializing the Map; the name of a pair MUST be serialized as a JSON string and the value of the pair, an instance of ActionAffordance, MUST be serialized as a JSON object.

All name-value pairs of an instance of ActionAffordance, where the name is a Vocabulary Term included in (one of) the Signatures of ActionAffordance or InteractionAffordance, MUST be serialized as members of the JSON object that results from serializing the ActionAffordance instance, with the Vocabulary Term as name.

The values assigned to input and output in an instance of ActionAffordance MUST be serialized as JSON objects. They rely on the Class DataSchema, whose serialization is defined in 6.3.10 Data Schemas.

The value assigned to forms in an instance of ActionAffordance MUST be serialized as a JSON array containing one or more JSON object serializations as defined in 6.3.9 forms.

A TD snippet of an Action affordance is given below:

In a Thing instance, the value assigned to events is a map of instances of EventAffordance. All name-value pairs of a Map of EventAffordance instances MUST be serialized as members of the JSON object that results from serializing the Map; the name of a pair MUST be serialized as a JSON string and the value of the pair, an instance of EventAffordance, MUST be serialized as a JSON object.

All name-value pairs of an instance of EventAffordance, where the name is a Vocabulary Term included in (one of) the Signatures of EventAffordance or InteractionAffordance, MUST be serialized as members of the JSON object that results from serializing the EventAffordance instance, with the Vocabulary Term as name.

The values assigned to subscription, data, and cancellation in an instance of EventAffordance MUST be serialized as JSON objects. They rely on the Class DataSchema, whose serialization is defined in 6.3.10 Data Schemas.

The value assigned to forms in an instance of EventAffordance MUST be serialized as a JSON array containing one or more JSON object serializations as defined in 6.3.9 forms.

A TD snippet of an Event object is given below:

Event affordances have been defined in a flexible manner, in order to adopt existing (e.g., WebSub [websub]) or customer-oriented event mechanisms (e.g., Webhooks). For this reason, subscription and cancellation can be defined according to the desired mechanism. Please find further details in [WOT-BINDING-TEMPLATES]. Example A.3 Webhook Event Example illustrates how Events can use subscription and cancellation to describe Webhooks.

All name-value pairs of an instance of Link, where the name is a Vocabulary Term included in the Signature of Link, MUST be serialized as members of the JSON object that results from serializing the Link instance, with the Vocabulary Term as name.

It is recommended to follow the link relation values as provided in Section 5.3.4.1 Link. The examples provided below demonstrate the use of different link relation types.

A reference can be provided that points to a Thing (e.g., a controller) that controls the underlying unit (e.g., a lamp). For this controlledBy can be used:

To point to a developer documentation of a Thing the value service-doc can be used:

Example 28

: Link to developer documentation

{
       // ...
       "links": [{
           "rel": "service-doc",
           "href": "https://example.com/howTo",
           "type": "application/pdf",
           "hreflang": "en"
       }]
       // ...
}

A superordinate Thing can collect a group of Things and refer to them by using the item value:

Example 29

: An electric drive includes two motors.

{
       "title": "Electric Drive",
       // ...
       "links": [{
           "rel": "item",
           "href": "coaps://motor1.example.com",
           "type": " application/td+json"
       },
       {
           "rel": "item",
           "href": "coaps://motor2.example.com",
           "type": " application/td+json"
       }]
       // ...
}

A Thing refers to a group in which it is collected with the collection value:

Example 30

: An electric motor is member of the electric drive collection.

{
       "title": "Electric Motor 1",
       "base": "coaps://motor1.example.com",
       // ...
       "links": [{
           "rel": "collection",
           "href": "coaps://drive.example.com",
           "type": " application/td+json"
       }]
       // ...
}

All name-value pairs of an instance of Form, where the name is a Vocabulary Term included in the Signature of Form, MUST be serialized as members of the JSON object that results from serializing the Form instance, with the Vocabulary Term as name.

If required, form objects MAY be supplemented with protocol-specific Vocabulary Terms identified with a prefix. See also 8.3 Protocol Bindings.

A TD snippet of a form object in the forms array is given below:

href may also carry a URI that contains dynamic variables such as lat and lon in http://example.org/weather/?lat=35&lon=139. In that case the URI can be defined as template as defined in [RFC6570]: http://example.org/weather/{?lat,long}.

In such a case, the URI Template variables MUST be collected in the JSON-object based uriVariables member either in the Thing level or in Interaction Affordance level with the associated (unique) variable names as JSON names.

The serialization of each value in the map assigned to uriVariables in an instance of Form MUST rely on the Class DataSchema, whose serialization is defined in 6.3.10 Data Schemas.

A TD snippet using a URI Template for query parameters and uriVariables in the Interaction Affordance level is given below:

Example 32

{
    "@context": "https://www.w3.org/2022/wot/td/v1.1",
    // ...
    "properties": {
        "weather": {
            // ...
            "uriVariables": {
                "lat": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 90,
                    "description": "Latitude for the desired location in the world" },
                "long": {
                    "type": "number",
                    "minimum": -180,
                    "maximum": 180,
                    "description": "Longitude for the desired location in the world" }
            },
            "forms": [{
              "href": "http://example.org/weather/{?lat,long}",
              "htv:methodName": "GET"
            }]
        },
        // ...
    },
    // ...
}

Alternatively, as defined in [RFC6570], uriVariables can be used for replacing the href structure. An example TD is provided below where a valid request to get the forecast of Bogota, Colombia would be an HTTP GET request to http://example.org/weather/bogota:

Example 33

{
    "@context": "https://www.w3.org/2022/wot/td/v1.1",
    // ...
    "properties": {
        "weather": {
            // ...
            "uriVariables": {
                "city": {
                    "type": "string",
                    "description": "City name to find the weather information for"
                }
            },
            "forms": [{
                "href": "http://example.org/weather/{city}",
                "htv:methodName": "GET"
            }]
        },
        // ...
    },
    // ...
}

The two examples below can be also combined, while using the same uriVariables feature. An HTTP GET request to http://example.org/weather/bogota/?unit=Celsius can be described as follows:

Example 34

{
    "@context": "https://www.w3.org/2022/wot/td/v1.1",
    // ...
    "properties": {
        "weather": {
            // ...
            "uriVariables": {
                "city": {
                    "type": "string",
                    "description": "City name to find the weather information for"
                },
                "unit": {
                    "type": "string",
                    "enum": ["fahrenheit_value","celsius_value"],
                    "description": "Desired unit for the temperature value"
                }
            },
            "forms": [{
                "href": "http://example.org/weather/{city}/{?unit}",
                "htv:methodName": "GET"
            }]
        },
        // ...
    },
    // ...
}

uriVariables are mainly for properties and events. When retrofitting an existing system, it may be necessary to use uriVariables for actions. In general, it is recommended to avoid uriVariables as much as possible when a new WoT-based system is designed.

The contentType member is used to assign a media type [RFC2046] including media type parameters as attribute-value pairs separated by a ; character. Example:

Example 35

{
    // ...
    "contentType": "text/plain; charset=utf-8",
    // ...
}

In some use cases, the form metadata of the Interaction Affordance not only describes the request, but also provides metadata for the expected response. For instance, an Action takePhoto defines an input schema to submit parameter settings of a camera (aperture priority, timer, etc.) using JSON for the request payload (i.e., "contentType": "application/json"). The output of this action is the photo taken, which is available in JPEG format, for example. In such cases, the response member is used to indicate the representation format of the response payload (e.g., "contentType": "image/jpeg"). Here no output schema is required, as the content type fully specifies the representation format.

If present, the value assigned to response in an instance of Form MUST be a JSON object. If present, the response object MUST contain a contentType member as defined in the Class definition of ExpectedResponse.

A form snippet with the response member is shown below based on the takePhoto Action described above:

Example 36

{
    // ...
    "actions": {
        "takePhoto": {
            // ...
            "forms": [{
                "op": "invokeaction",
                "href": "http://camera.example.com/api/snapshot",
                "contentType": "application/json",
                "response": {
                    "contentType": "image/jpeg"
                }
            }]
        }
    },
    // ...
}

In some cases, the message received from the Thing as part of an Interaction Affordance can differ due to different reasons. Such reasons could be error cases or alternative responses for a valid response. In these cases, additionalResponses terms can be used to describe this behavior.

For example, an Action Affordance to turn on a car engine may not work in bad weather conditions or in case the engine needs maintenance. In such a case, the Thing needs to reply with payloads that are not usually used.

A TD snippet with the additionalResponses member in an Action Affordance is shown below. It describes the case mentioned above when an error response can be sent with another payload than what is described in the output. The success with the value false refers to the fact that this payload refers to an error case and schema allows linking to the payload description used at schemaDefinitions:

Example 37

{
    // ...
    "schemaDefinitions": {
      "actionErrorPayload": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "enum": ["cold","hot","maintenance"]
          },
          "timeStamp": {
            "description": "UNIX time in numbers indicating when the error happened",
            "type": "number"
          }
        }
      }
    },
    // ...
    "actions": {
        "startEngine": {
            "output": {
              "type": "string"
            },
            "forms": [{
                "op": "invokeaction",
                "href": "http://mycar.example.com/api/engine",
                "contentType": "application/json",
                "additionalResponses": [{
                    "success": false,
                    "contentType": "application/json",
                    "schema": "actionErrorPayload"
                }]
            }]
        }
    },
    // ...
}

The additionalResponses term can be used in non-error cases as well. In that case, success is set to true and another schema can be used to describe the payload.

In some cases binary data is embedded in text-based values, e.g., a JSON string-based value embeds a base64 encoded image. The terms contentMediaType and contentEncoding can be used to clarify the context and encoding format of such name-value pairs. A sample usage of contentMediaType and contentEncoding is shown below:

Example 38

{
    // ...
    "properties": {
        "image": {
                "description": "Provides latest image",
                "type": "string",
                "contentMediaType": "image/png",
                "contentEncoding": "base64",
                "forms": [{
                            "op": "readproperty",
                            "href": "coaps://mylamp.example.com/lastPicture",
                            "cov:methodName": "GET",
                            "contentType": "application/json"
                    }]
        }
    },
    // ...
}

When forms is present at the top level, it can be used to describe meta interactions offered by a Thing. For example, the operation types readallproperties and writeallproperties are for meta interactions with a Thing by which Consumers can read, write or observe all properties at once. In the example below, a forms member is included in the TD root object and the Consumer can use the submission target https://mylamp.example.com/properties both to read or write all Properties (i.e., on, brightness, and timer) of the Thing in a single protocol transaction.

Example 39

{
    // ...
    "properties": {
        "on": {
            "type": "boolean",
            "forms": [...]
        },
        "brightness": {
            "type": "number",
            "forms": [...]
        },
        "timer": {
            "type": "integer",
            "forms": [...]
        }
    },
    // ...
    "forms": [{
        "op": "readallproperties",
        "href": "https://mylamp.example.com/properties",
        "contentType": "application/json",
        "htv:methodName": "GET"
    },
    {
        "op": "writeallproperties",
        "href": "https://mylamp.example.com/properties",
        "contentType": "application/json",
        "htv:methodName": "PUT"
    }]
}

Thing-level uriVariables can be used here to supply further variables to the operation or to specify a list of Property Affordance names for a readmultipleproperties operation. In the example below, the unit for the properties can be set via such a variable and the desired list of properties can be set:

Example 40

{
    // ...
    "properties": {
        "temperature": {
            "type": "number",
            "forms": [...]
        },
        "brightness": {
            "type": "number",
            "forms": [...]
        },
        "humidity": {
            "type": "integer",
            "forms": [...]
        }
    },
    "uriVariables": {
        "propertyNames": {
            "type": "string",
            "description": "Comma separated list of property names to select."
        },
        "unitSystem": {
            "type": "string",
            "enum": ["metric_value","imperial_value","uscustomary_value"],
            "description": "System of Measurement that will be used for the values"
        }
    },
    "forms": [{
        "op": "readallproperties",
        "href": "https://mything.example.com/properties{?unitSystem}",
        "contentType": "application/json",
        "htv:methodName": "GET"
    },
    {
        "op": "readmultipleproperties",
        "href": "https://mylamp.example.com/properties{?propertyNames,unitSystem}",
        "contentType": "application/json",
        "htv:methodName": "GET"
    }]
}

For a readmultipleproperties operation, an example HTTP GET request to the URI https://mylamp.example.com/properties?propertyNames=humidity,temperature&unitSystem=metric would return the values humidity and temperature Property Affordances, with the metric System of Measurement.

In the case of operation type writeallproperties, it is expected that the Consumer provides all writable (non readOnly) properties and the (new) assigned values (e.g., within payload). Similarly, for the writemultipleproperties operation type, it is expected that the Consumer provides writable (non readOnly) properties. On the Thing side, Thing is expected to return readable (non writeOnly) properties in the case of readmultipleproperties and readallproperties operation types.

The data schemas of the WoT Thing Description defined through the DataSchema Class are based on a subset of the JSON Schema terms [JSON-SCHEMA]. Thus, serializations of the TD data schemas can be fed directly into JSON Schema validator implementations to validate the data exchanged with Things.

Data schema serialization applies to PropertyAffordance instances, the values assigned to input and output in ActionAffordance instances, the values assigned to subscription, data, and cancellation in EventAffordance instances, and the value assigned to uriVariables in instances of Subclasses of InteractionAffordance (when a form object uses a URI Template).

All name-value pairs of an instance of one of the Subclasses of DataSchema, where the name is a Vocabulary Term included in the Signature of that Subclass or in the Signature of DataSchema, MUST be serialized as members of the JSON object that results from serializing the DataSchema Subclass's instance, with the Vocabulary Term as name.

The value assigned to properties in an instance of ObjectSchema MUST be serialized as a JSON object.

The values assigned to enum, required, and oneOf in an instance of DataSchema MUST be serialized as a JSON array.

The value assigned to items in an instance of ArraySchema MUST be serialized as a JSON object or a JSON array containing JSON objects.

A TD snippet data schema members is given below. Note that the surrounding object may be a data schema object (e.g., for input and output) or a Property object, which would contain additional members.

The terms readOnly and writeOnly can be used to signal which data items are exchanged in read interactions (i.e., when reading a Property) and which in write interactions (i.e., when writing a Property). This can be used as a workaround when Properties of an unconventional Thing exhibit different data for reading and writing, which can be the case when augmenting an existing device or service with a Thing Description.

A TD snippet with the usage of readOnly and writeOnly is given below:

Example 42

{
    // ...
    "properties": {
        "status": {
            "description": "Read or write On/Off status.",
            "type": "object",
            "properties": {
                "latestStatus": {
                    "type": "string",
                    "enum": ["on_value", "off_value"],
                    "readOnly": true
                },
                "newSt

Read the original on w3.org ↗