Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Split operation and messageType into separate members of a message #42

Open
benfrancis opened this issue Feb 10, 2025 · 0 comments

Comments

@benfrancis
Copy link
Member

benfrancis commented Feb 10, 2025

This proposal builds on @hspaay's message envelope proposal in #34 (and #32), and @RobWin's suggestion for acknowledgements of certain messages (e.g. #29).

It is a further exploration of the idea of splitting operation and messageType into separate members of a message, where operation is an op name taken directly from the Thing Description specification and messageType is one of three basic types: request, response and notification.

I've kept response and notification separate as per @hspaay's original proposal because I do think the two are meaningfully different, though I still feel a bit uneasy about this because "notification" is not a clearly defined concept in existing WoT specifications. It also kind of mixes up the common request/response and publish/subscribe design patterns.

Although I have adopted the proposal of a consistent "name" member to contain the name of the affordance the message relates to, one way this proposal differs from @hspaay's proposal is that it keeps separate members for different data payloads depending on the type of operation, rather try to combine everything into input and output. This is intended to make the mapping of data schemas from a Thing Description more obvious and not have members with the same name but different meanings:

  • Property-related messages have a "value" (conforming to the data schema of PropertyAffordances)
  • Action related messages have an "input" and an "output" (conforming to the input and output data schemas in ActionAffordances) and a "status" (consistent with the HTTP Basic Profile)
  • Event related messages have event "data" (conforming to the data member in EventAffordances)

Another way that this proposal differs is that there are never multiple responses to a request, only multiple notifications and a single response. This is achieved by property observations and event subscriptions having a request, response then notifications, and action invocations having a request, notifications then a single response.

Message Types

  • request
  • response
  • notification

Operations

Operation Lifecycle
readproperty request, response
writeproperty request, response
observeproperty request, response, notification, notification...
unobserveproperty request, response
readallproperties request, response
writeallproperties request, response
readmultipleproperties request, response
writemultipleproperties request, response
observeallproperties request, response, notification, notification...
unobserveallproperties request, response
invokeaction request, notification, notification... response *
queryaction request, response
queryallactions request, response
subscribeevent request, response, notification, notification...
unsubscribeevent request, response
subscribeallevents request, response, notification, notification...
unsubscribeallevents request, response

* I'm a bit uneasy about the lifecycle of the invokeaction operation because we have kind of invented a combined invokeaction/observeaction operation, which doesn't exist in the Thing Description specification. There is currently no way to specify the data schema of an action status and no way to observe the status of a property in the the TD spec.

Examples

readproperty

Request

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "c370da58-69ae-4e83-bb5a-ac6cfb2fed54",
  "messageType": "request",
  "operation": "readproperty",
  "name": "on",
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

Success Response

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "79057736-3e0e-4dc3-b139-a33051901ee2",
  "messageType": "response",
  "operation": "readproperty",
  "name": "on",
  "value": true,
  "timestamp": "2024-01-13T23:20:50.52Z",
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

Error Response

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "79057736-3e0e-4dc3-b139-a33051901ee2",
  "messageType": "response",
  "operation": "readproperty",
  "name": "on",
  "error": {
    "status": "404",
    "type": "https://w3c.github.io/web-thing-protocol/errors#not-found",
    "title": "Not Found"
    "detail": "No property found with the name 'on'"
  }
  "timestamp": "2024-01-13T23:20:50.52Z",
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

writeproperty

Request

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "adbefb2c-9c10-4a9e-b2d5-840a58ab667e",
  "messageType": "request",
  "operation": "writeproperty",
  "name": "on",
  "value": true,
  "correlationID": "b737e900-2b34-4315-bf9e-9eec1a0406c0"
}

Response

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "79057736-3e0e-4dc3-b139-a33051901ee2",
  "messageType": "response",
  "operation": "writeproperty",
  "name": "on",
  "value": true,
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

Note: To address the issue raised in #38 about non-confirmable writes, a value could only be provided in a response if it is confirmed to have been written.

observeproperty

Request

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "c370da58-69ae-4e83-bb5a-ac6cfb2fed54",
  "messageType": "request",
  "operation": "observeproperty",
  "name": "on",
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

Response

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "79057736-3e0e-4dc3-b139-a33051901ee2",
  "messageType": "response",
  "operation": "observeproperty",
  "name": "on",
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

Notification

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "79057736-3e0e-4dc3-b139-a33051901ee2",
  "messageType": "notification",
  "operation": "observeproperty",
  "name": "on",
  "value": true,
  "timestamp": "2024-01-13T23:20:50.52Z",
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

unobserveproperty

Request

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "c370da58-69ae-4e83-bb5a-ac6cfb2fed54",
  "messageType": "request",
  "operation": "unobserveproperty",
  "name": "on",
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

Response

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "79057736-3e0e-4dc3-b139-a33051901ee2",
  "messageType": "response",
  "operation": "unobserveproperty",
  "name": "on",
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

readallproperties

Request

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "c370da58-69ae-4e83-bb5a-ac6cfb2fed54",
  "messageType": "request",
  "operation": "readallproperties",
  "name": "on",
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

Response

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "79057736-3e0e-4dc3-b139-a33051901ee2",
  "messageType": "response",
  "operation": "readpallproperties",
  "name": "on",
  "values": {
    "on": true,
    "level": 50
  },
  "timestamp": "2024-01-13T23:20:50.52Z",
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

readmultipleproperties

Request

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "c370da58-69ae-4e83-bb5a-ac6cfb2fed54",
  "messageType": "request",
  "operation": "readmultipleproperties",
  "names": ["on", "level"],
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

Response

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "79057736-3e0e-4dc3-b139-a33051901ee2",
  "messageType": "response",
  "operation": "readmultipleproperties",
  "name": "on",
  "values": {
    "on": true,
    "level": 50
  },
  "timestamp": "2024-01-13T23:20:50.52Z",
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

invokeaction

Request

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "c370da58-69ae-4e83-bb5a-ac6cfb2fed54",
  "messageType": "request",
  "operation": "invokeaction",
  "name": "fade",
  "input": {
    "level": 100,
    "duration": 5
  }
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

Notification

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "c370da58-69ae-4e83-bb5a-ac6cfb2fed54",
  "messageType": "notification",
  "operation": "invokeaction",
  "name": "fade",
  "status": "running",
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

Response

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "c370da58-69ae-4e83-bb5a-ac6cfb2fed54",
  "messageType": "response",
  "operation": "invokeaction",
  "name": "fade",
  "output": true,
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

queryaction

Request

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "c370da58-69ae-4e83-bb5a-ac6cfb2fed54",
  "messageType": "request",
  "operation": "queryaction",
  "name": "fade",
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

Response

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "c370da58-69ae-4e83-bb5a-ac6cfb2fed54",
  "messageType": "response",
  "operation": "queryaction",
  "name": "fade",
  "status": "completed",
  "output": true,
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

queryallactions

Request

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "c370da58-69ae-4e83-bb5a-ac6cfb2fed54",
  "messageType": "request",
  "operation": "queryallactions",
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

Response

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "c370da58-69ae-4e83-bb5a-ac6cfb2fed54",
  "messageType": "response",
  "operation": "queryallactions",
  "statuses": {
    "fade": {
      [
         {
          "status": "pending",
          "correlationID": "542e4567-e89b-12d3-a456-631968",
          "timeRequested": "2024-11-11T11:43:20.135Z"
        },
        {
          "status": "completed",
          "correlationID": "321e4567-e89b-12d3-a456-531531",
          "timeRequested": "2024-11-10T11:43:20.135Z",
          "timeEnded": "2024-11-10T11:43:25.135Z",
          "output": true
        }
    ]
  },
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

subscribeevent

Request

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "c370da58-69ae-4e83-bb5a-ac6cfb2fed54",
  "messageType": "request",
  "operation": "subscribeevent",
  "name": "overheated",
  "lastEventID": "0b69db8d-9b5a-4801-be76-8eb8f4af0d4a",
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

Response

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "79057736-3e0e-4dc3-b139-a33051901ee2",
  "messageType": "response",
  "operation": "subscribeevent",
  "name": "overheated",
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

Notification

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "79057736-3e0e-4dc3-b139-a33051901ee2",
  "messageType": "notification",
  "operation": "subscribeevent",
  "name": "overheated",
  "data": 90,
  "timestamp": "2024-01-13T23:20:50.52Z",
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

I don't have a complete set of examples yet and there are still some questions that I think would need answering, but I wanted to see what people thought.


Notes:

  1. In this proposal there would be no separate error message type, since the error would be contained in a response.
  2. The ping and pong messages from the strawman proposal also don't fit neatly into this approach, though I'm not completely sure they're needed.
  3. I'm not sure about how correlationIDs should work in queryaction and queryallactions messages, but I will file a separate issue for that.
  4. I was too lazy to generate unique UUIDs for every message and match up correlationIDs, but hopefully you get the idea.
@benfrancis benfrancis changed the title Split operation and messageType into separate members of a message Proposal: Split operation and messageType into separate members of a message Feb 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant