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

Is there a need for invokeanyaction/queryallactions operations? #1200

Closed
benfrancis opened this issue Jul 22, 2021 · 13 comments
Closed

Is there a need for invokeanyaction/queryallactions operations? #1200

benfrancis opened this issue Jul 22, 2021 · 13 comments
Labels
Propose closing Problem will be closed shortly if there is no veto.

Comments

@benfrancis
Copy link
Member

benfrancis commented Jul 22, 2021

Now that we have subscribeallevents/unsubscribeallevents operations it is possible to have top level forms in a Thing Description for both properties and events. E.g.

  "forms": [
    {
      "op": ["readallproperties", "writeallproperties"],
      "href": "./properties"
    },
    {
      "op": ["subscribeallevents", "unsubscribeallevents"],
      "href": "./events"
    }
  ]

In addition to these top level Properties and Events endpoints, WebThings also provides a top level Actions endpoint for things. This endpoint has a couple of functions:

  • Invoke an action of any type
  • Get a list of all pending action requests for all action types

The Actions endpoint is really just provided as a convenience since:

  • Actions can be invoked on individual Action endpoints
  • A list of all pending action requests can be produced by individually querying every action resource and concatenating the results into a list

I'm curious to know whether people would find value in invokeanyaction/queryallactions operations such that actions could also have a top level form, e.g.

  "forms": [
    {
      "op": ["invokeanyaction", "queryallactions"],
      "href": "./actions"
    }
  ]

I think it would be neat to have all three, but how useful is it?

(The alternative is that we drop this feature from WebThings).

@egekorkan
Copy link
Contributor

I would say that once querying actions is possible, such an endpoint would be needed. invokeanyaction is a bit weird since that is what the forms in the actions are for

@benfrancis
Copy link
Member Author

@egekorkan wrote:

invokeanyaction is a bit weird since that is what the forms in the actions are for

The same argument could apply to querying actions, as a GET request on the action endpoint could return a list of all pending action requests for that action.

I think there are three possible use cases for "querying" an action:

  1. Getting an individual ActionStatus resource regarding an individual action request (e.g. GET /actions/fade/1935-5939-ngu3)
  2. Getting a list of pending action requests for a given action (e.g. GET /actions/fade)
  3. Getting a list of pending action requests for all actions (e.g. GET /actions)

@sebastiankb
Copy link
Contributor

I would be ok for having queryallactions as a new op type. However, I also do not see the motivation for invokeanyaction either. Is the idea to invoke multiple actions at the same time?

@benfrancis
Copy link
Member Author

I also do not see the motivation for invokeanyaction either. Is the idea to invoke multiple actions at the same time?

No it's really just a single endpoint from which you can invoke any action, rather than using the endpoint specific to a particular action affordance.

In the Web Thing API it's mostly just provided for symmetry (you can send both a GET and a POST to an Action resource, so you can send both a GET and POST to an Actions resource too), but I agree it doesn't add much utility.

@sebastiankb
Copy link
Contributor

sebastiankb commented Jul 28, 2021

from today's TD call:

  • group agree to introduce the "query" op type for the top level forms. Maybe we need a different name to be more clear (e.g., queryallactiveactions)
  • group also agree about invoking multiple actions (this would also cover the invokeanyaction), however, we need to clearify more details like what happen if one actions fails, how the response looks like, etc
  • @benfrancis would provide PR based on the query approach first, however, like to get feedback from the comment in this issue here
  • for record, some examples about the different op types:

invokeaction - POST /actions/fade {"level": 100, "duration": 10}
invokeanyaction - POST /actions {"fade": {{"level": 100, "duration": 10}}
invokemultipleactions - POST /actions {"fade": {{"level": 100, "duration": 10}, "reboot": {}}

@benfrancis
Copy link
Member Author

As discussed in the call, we probably need to agree how to cancel and query the status of an action request (#302) first, before deciding on these operations for top level action forms.

The proposal I'm hoping to get feedback on is #302 (comment), which demonstrates proposed queryaction and cancelaction operations, originally proposed by @egekorkan.

@benfrancis
Copy link
Member Author

Another thought, what about cancelallactions?

@benfrancis
Copy link
Member Author

As a starting point, I could create a PR to add queryallactions?

See #302 (comment) for a proposal regarding operation naming (queryactioninstance, queryaction, queryallactions).

@benfrancis
Copy link
Member Author

benfrancis commented Sep 9, 2021

As raised in #302 (comment), what should the default data schema of a queryallactions operation be?

For the meta interactions of properties the specification says the following:

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.

We could apply a similar approach to queryallactions by defining its data schema as a map of all action data schemas keyed by action name but, unlike properties, actions do not have a single data schema. Actions have an input data schema and an output data schema and as the example in #302 (comment) demonstrates may also have a separate response data schema for different operations.

We could define that the response data schema of queryallactions is a map of the responses of all queryaction operations, but what if:

  1. An action affordance doesn't define a queryaction operation (e.g. because it only defines a queryactioninstance operation)
  2. A queryaction operation doesn't define a response schema (since that's technically optional, though not very useful if omitted)

We could define no default data schema for a queryallactions operation and require that it defines its own response schema (assuming that schemaDefinitions becomes allowed in an ExpectedResponse object as planned), but Thing Descriptions may start to be extremely verbose with this completely declarative approach.

@egekorkan
Copy link
Contributor

There's a somewhat similar issue with events with the subscribeallevents op keyword. Not all events return a payload. I would say that the affordance name is simply omitted in the map?

@benfrancis
Copy link
Member Author

@egekorkan wrote:

There's a somewhat similar issue with events with the subscribeallevents op keyword.

Hmm, I guess that depends on how the subscription mechanism works. I imagine in most cases each event will be pushed separately when it occurs so there's no need for a combined schema.

would say that the affordance name is simply omitted in the map?

I'm not sure I understand, if the affordance name is omitted then how would a Consumer distinguish between instances of different actions? E.g.

{
  "fade": [
    {
      "status": "completed",
      "href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655"
    },
    {
      "status": "pending",
      "href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a456-431553"
    },
    {
      "status": "pending",
      "href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a456-51ff16"
    }
  ],
  "reboot": [
    {
      "status": "pending",
      "href": "/things/lamp/actions/reboot/123e4567-e89b-12d3-a456-f3dea"
    }
  ]
}

vs.

  [
    {
      "status": "completed",
      "href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655"
    },
    {
      "status": "pending",
      "href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a456-431553"
    },
    {
      "status": "pending",
      "href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a456-51ff16"
    },
    {
      "status": "pending",
      "href": "/things/lamp/actions/reboot/123e4567-e89b-12d3-a456-f3dea"
    }
]

@egekorkan
Copy link
Contributor

Sorry about the confusion. What I meant is the first example posted in the above comment. If one action does not return something for querying, either the action name is omitted from the map or its value is left empty. Leaving the value empty could be reserved for empty payloads though. So in the example above, if reboot cannot be queried, the response of queryallactions can be simply:

{
  "fade": [
    {
      "status": "completed",
      "href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655"
    },
    {
      "status": "pending",
      "href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a456-431553"
    },
    {
      "status": "pending",
      "href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a456-51ff16"
    }
  ]
 // nothing here since reboot does not allow querying
}

@egekorkan
Copy link
Contributor

I think that with having queryallactions and no interest for the other proposals, I would be proposing to close this

@egekorkan egekorkan added the Propose closing Problem will be closed shortly if there is no veto. label Jun 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Propose closing Problem will be closed shortly if there is no veto.
Projects
None yet
Development

No branches or pull requests

3 participants