-
Notifications
You must be signed in to change notification settings - Fork 63
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
Specify the result of queryaction
operation
#2068
Comments
Querying an action morphologically is similar to a microservice API, where the questions are:
I suggest serious simplifications here, which we can safely make IMHO. That means WoT specifications MUST contain algorithms what kind of service to start together with an action and what is its lifecycle and interface. Things might choose to not implement these and report error or just time out. On the client side the WoT spec should contain algorithmic steps on how to deal with these situations. I propose to start with a simple solution that allows later extensions and composition.
|
@relu91 wrote:
I agree it is unclear how
This is an interesting idea that I'm not sure has been suggested before. One complication is the difference in behaviour between synchronous and asynchronous actions. With synchronous actions there may just be an input in a request and an output in a response. With asychronous actions there may be no output in an initial response, but the response to a @zolkis wrote:
Note that we currently have
You are describing this as if it's a JavaScript API, but a Thing Description is just metadata which needs to be able to describe a range of different ways actions may be modelled in different protocols. Just a reminder of the existing work done on this in the HTTP Basic Profile which provides an example of how synchronous and asynchronous actions may be modelled in HTTP, including an example of an ActionStatus payload format. Also the previous discussion in #1408 and #1665 about the ambiguity around |
Right, we also need to specify the result of
Yes, we can start doing that :). I deliberately used scripting terms, partly continuing today's Scripting discussion in the wrong repo/issue :), but also as an input/nudge from a developer point of view. Modeling should allow security hardening, for which validation (in the most commonly used platforms) is essential. |
I suppose you could use a JSON Pointer to include the output schema in the status schema...? My next question would be how does a Consumer know what the status schema means? |
Thank you for all the inputs, as discussed in the call, I'm afraid that the simple solution presented in my first post does not really cover the complexity of our use cases space. It is better to look for a more robust and consistent proposal and the discussion should be framed next to the existing discussions around "manageable actions" and/or "how to express relationships between affordances". There we should handle all the complex scenarios described above by @benfrancis, with maybe the expection of
Which I think would be pretty dependent on (exposer or consumer) application logic (or action types). Here we should answer, how we are going to deal with this grey space left by the spec for TD 1.1 implementers. I think that given nothing is guaranteed we should always assume the worst (in lack of out-band information, like the protocol used).
Let's continue the discussion there. |
TD Call Today:
|
I keep thinking about @relu91's idea of a Building on the example I gave in w3c/wot-binding-templates#408, I've tried to describe the action queue defined in the HTTP Basic Profile using a {
"actions": {
"fade": {
"title": "Fade",
"description": "Fade the lamp to a given level",
"synchronous": false,
"input": {
"type": "object",
"properties": {
"level": {
"type": "integer",
"minimum": 0,
"maximum": 100,
"unit": "percent"
},
"duration": {
"type": "integer",
"minimum": 0,
"unit": "milliseconds"
}
}
},
"output": {
"type": "boolean"
},
"status": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"pending",
"running",
"completed",
"failed"
]
},
"output": {
"$ref": "#../../../output"
},
"error": {
"type": "object"
},
"href": {
"type": "string",
"format": "uri",
"const": "./actions/fade/{id}"
},
"timeRequested": {
"type": "string",
"format": "date-time"
},
"timeEnded": {
"type": "string",
"format": "date-time"
}
},
"required": [
"status"
]
},
"forms": [
{
"op": "invokeaction",
"href": "actions/fade",
"htv:methodName": "POST",
"response": {
"htv:statusCodeNumber": 201,
"htv:headers": [
{
"htv:fieldName": "Location",
"htv:fieldValue": "actions/fade/{id}"
}
]
}
},
{
"op": "queryaction",
"href": "actions/fade/{id}",
"htv:methodName": "GET"
},
{
"op": "cancelaction",
"href": "actions/fade/{id}",
"htv:methodName": "DELETE"
}
],
"uriVariables": {
"id": {
"@type": "htv:ActionID",
"type": "string",
"description": "identifier of action request"
}
}
}
},
"forms": [
{
"op": "queryallactions",
"href": "actions",
"htv:methodName": "GET"
}
]
} This is quite verbose, especially if it needs to be repeated for every action, but it could potentially work. A TD author could use Note that I've also used the Other questions that would need to be answered:
|
We could avoid more ad-hoc operations and/or even thin the number further and uniform the behavior by making it more composable e.g.:
Reusable components would allow to have fairly compact TDs. |
@lu-zero wrote:
Making action status a property doesn't solve the problem of needing dynamic resources to represent the status of each concurrent action request. It just means the Consumer now needs to reason about the relationship between three different affordances, complicating implementation further.
Whilst I can see why this might seem neat, I strongly dislike this idea, for reasons I'm happy to expand upon but probably off topic for this issue. |
"dynamic resources" aren't just for querying the status so I wouldn't have something ad-hoc for that specific situation as much as I'd rather not have something ad-hoc like It isn't much different from modeling a database access as properties e.g. the infamous weather forecast service. |
@lu-zero wrote:
That seems to be a general assumption, which is why we have been waiting for years for a general purpose solution. And yet in practice I've personally never come across another use case when describing a connected device as a Web Thing, have you?
Devices are not databases and we are not designing a database API. I've spent a lot of time trying to find alternative ways of modelling multiple concurrent long-running actions in a HTTP REST API that don't involve creating separate resources to represent status, and I haven't been able to find a good one. Regardless, if everything has to be describable in a TD then we need to be able to describe real REST APIs, which do model long running operations this way. I think @relu91 is right that we need a data schema to describe action status, as distinct from the input and output of the action. |
A printer is a device, you wouldn't want to have a separate resource for each job. I agree we need at least 1 data schema, possibly 2. |
Back when dinosaurs walked the earth, print jobs were submitted to shared printers, and each got its own identifier, which was made known to the submitter. This enabled submitters to watch the queue. They could see that their job had finished, so they would know to go to the delivery area; or they might see that their job had failed, for whatever reason (postscript errors happen when you're writing your own printer driver, hand-coding postscript, etc., as part of your Computer Science coursework; there are also paper jams that can require a resubmission of a page or a job; etc.).... There are more reasons you might want to have a separate resource for each job. |
In that case you have an identifier and you use it on a single route (per command) that is not dynamically produced. |
This is actually exactly the kind of use case I have in mind, e.g. Sending print jobs to a thermal printer. Modelling a queue or long running operations as multiple resources seems to be a very established pattern in REST APIs. The default HTTP method for invokeaction is POST, which is used for creating new resources.
I'm not sure how that makes any difference. |
The problem we have is that, besides with security schemes and uriVariables, we do not have a way to model a property that takes the identifier as argument. If we address that we should be fine. |
The current specification for the
queryaction
operation lacks clarity regarding the expected result. We have the corresponding data schema definition for other operations, while here, we don't. Probably, we should discuss introducing an additional field next toinput
andoutput
calledstatus
where one can define the shape of data coming as result ofqueryaction
or in the futureobserveaction
.The text was updated successfully, but these errors were encountered: