Skip to content

Strawman Proposal: HTTP Sub-protocol #116

@benfrancis

Description

@benfrancis

We recently published a first draft of the Web Thing Protocol WebSocket Sub-protocol, which is one of the two main deliverables in the Web Thing Protocol Community Group's charter.

The other main deliverable in our charter is the definition of an "HTTP sub-protocol for the Web of Things". The idea of this sub-protocol is to create a common protocol for communicating with connected devices over HTTP, enabling consumers to carry out the full set of WoT operations using the familiar pattern of a REST API (i.e. the same as our WebSocket sub-protocol, but using plain HTTP).

The goal is to enable out-of-the-box interoperability between WoT Consumers and WoT Things which support this sub-protocol, without Consumers having to parse complicated declarative protocol bindings, and without Things having to repeat the same declarative protocol binding in every Form of every InteractionAffordance in every Thing Description instance.

Strawman Proposal

I have created a very rough strawman proposal which defines an HTTP sub-protocol (alongside the current WebSocket sub-protocol) that is essentially a combination of the common HTTP Basic Profile and HTTP SSE Profile protocol bindings from the WoT Profiles specification, with Server-Sent Events (SSE) being used for event-based operations like observeproperty and subscribeevent.

To be clear, this HTTP sub-protocol would be an alternative to the protocol bindings from the WoT Profiles 1.0 specification which has currently stalled on the recommendation track of the Web of Things Working Group due to a lack of support for its approach. Rather than using the at-risk profiling mechanism via the profile member at the top level of Thing Descriptions, this would make use of the subprotocol member of Forms in the same way we use it for our WebSocket sub-protocol.

I'm still not completely sure that "HTTP Sub-protocol" is the right term for what this is. Since the HTTP specification doesn't formally define the concept of sub-protocols in the way that the WebSocket protocol does it might be more accurately described as an "HTTP-based application protocol" (other examples being ActivityPub, gRPC and GraphQL) or simply a "REST API". However, the subprotocol member in Thing Descriptions does provide a useful mechanism for us to refer to a common prescriptive protocol of this nature, and it is from this mechanism that the name is derived.

I would like to hear what people think about this approach to defining an HTTP Sub-protocol for the Web of Things, and whether other members would be interested in helping to properly specify and implement this sub-protocol.

To help illustrate how this would be used in a WoT Thing Description, please see the example Thing Description below, taken from Example 99 in the strawman proposal

{
  "@context": "https://www.w3.org/2022/wot/td/v1.1",
  "id": "https://mywebthingserver.com/things/lamp",
  "base": "https://mywebthingserver.com/things/lamp/",
  "title": "My Lamp",
  "description": "A web connected lamp",
  "securityDefinitions": {
    "oauth2": {
      "scheme": "oauth2",
      "flow": "code",
      "authorization": "https://mywebthingserver.com/oauth/authorize",
      "token": "https://mywebthingserver.com/oauth/token"
    }
  },
  "security": "oauth2",
  "properties": {
    "on": {
      "type": "boolean",
      "title": "On/Off",
      "description": "Whether the lamp is turned on",
      "forms": [
        {
          "href": "properties/on",
          "op": [
            "readproperty",
            "writeproperty",
            "observeproperty",
            "unobserveproperty"
          ],
          "subprotocol": "webthingprotocol"
        }
      ]
    },
    "level" : {
      "type": "integer",
      "title": "Brightness",
      "description": "The level of light from 0-100",
      "unit": "percent",
      "minimum" : 0,
      "maximum" : 100,
      "forms": [
        {
          "href": "properties/level",
          "op": [
            "readproperty",
            "writeproperty",
            "observeproperty",
            "unobserveproperty"
          ],
          "subprotocol": "webthingprotocol"
        }
      ]
    }
  },
  "actions": {
    "fade": {
      "title": "Fade",
      "description": "Fade the lamp to a given level",
      "synchronous": false,
      "input": {
        "type": "object",
        "properties": {
          "level": {
            "title": "Brightness",
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "unit": "percent"
          },
          "duration": {
            "title": "Duration",
            "type": "integer",
            "minimum": 0,
            "unit": "milliseconds"
          }
        }
      },
      "forms": [
        {
          "href": "actions/fade",
          "op": [
            "invokeaction",
            "queryaction",
            "cancelaction"
          ],
          "subprotocol": "webthingprotocol"
        }
      ]
    }
  },
  "events": {
    "overheated": {
      "title": "Overheated",
      "data": {
        "type": "number",
        "unit": "degree celsius"
      },
      "description": "The lamp has exceeded its safe operating temperature",
      "forms": [{
        "href": "events/overheated",
        "op": [
          "subscribeevent",
          "unsubscribeevent"
        ],
        "subprotocol": "webthingprotocol"
      }]
    }
  },
  "forms": [
    {
      "href": "properties",
      "op": [
        "readallproperties",
        "writemultipleproperties",
        "observeallproperties",
        "unobserveallproperties"
      ],
      "subprotocol": "webthingprotocol"
    },
    {
      "op": "queryallactions",
      "href": "actions",
      "subprotocol": "webthingprotocol"
    },
    {
      "op": [
        "subscribeallevents",
        "unsubscribeallevents"
      ],
      "href": "events",
      "subprotocol": "webthingprotocol"
    }
  ]
}

REST APIs like this are very common in both IoT cloud services (e.g. AWS IoT Core, Azure IoT Hub, IBM Watson IoT, Particle Cloud and Seam) and IoT gateways (e.g. WebThings Gateway, HomeAssistant, AWS IoT Greengrass and Smart Core OS), but they are almost always vendor-specific. This would be an attempt to provide an open standard for that type of API, which greenfield WoT implementations can opt into using in order to benefit from out-of-the-box interoperability.

Please let me know what you think.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions