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

uriVariables with multiple forms #1083

Open
relu91 opened this issue Mar 29, 2021 · 9 comments
Open

uriVariables with multiple forms #1083

relu91 opened this issue Mar 29, 2021 · 9 comments
Labels
Defer to TD 2.0 Forms Topics related to the forms container Has Use Case Potential The use case can be extracted and explained Needs discussion more discussion is needed before getting to a solution

Comments

@relu91
Copy link
Member

relu91 commented Mar 29, 2021

This issue is coming from a possible refactoring of the example Thing Description Directory TD provided in the Discovery document. In particular, it was proposed to model all different search methods as filters of a property affordance called things. See the concrete (simplified) example below:

{
  properties: {
     "things":  {
           "@type": "ThingListProperty",
            "uriVariables": {
                "id": {
                    "@type": "ThingID",
                    "type": "string",
                    "format": "iri-reference"
                },
                "jsonpath": {
                    "@type": "JSONPathExpression",
                    "type": "string"
                },
                "xpath": {
                    "@type": "XPathExpression",
                    "type": "string"
                },
                "query": {
                    "@type": "SPARQLQuery",
                    "type": "string"
                }
            },
            "forms": [
                {
                    "href": "/things/{id}"
                },
                {
                    "href": "/things?jsonpath={jsonpath}",
                },
                {
                    "href": "/things?xpath={xpath}",
                },
                {
                    "href": "/things?query={query}",
                }
            ]
        }
  }
}

As you can see the different uriVariables can be used only in one particular form as if they make sense only if used together with the right form. Notice that here splitting the things in multiple properties affordances does not really make sense.

Should we prescribe that a client can choose the right form using the input as a hint? or is it already been described in the spec?

References

@egekorkan
Copy link
Contributor

Should we prescribe that a client can choose the right form using the input as a hint? or is it already been described in the spec?

I think you mean uriVariables as a hint. Anyways, I think this kind of an explanation needs to be added to the spec. Something that says that "multiple forms can satisfy the operation (readproperty, subscribeevent, etc.) targeted by the Consumer. In this case, the Consumer should choose a form based on the way the Consumer operates such as the protocols or contentType it supports, choice of security mechanism or other mechanisms such as uri templating"

I couldn't find a better way to say " the way the Consumer operates " :/

@benfrancis
Copy link
Member

The Directory Service API is a bit of a special case because we have a concrete specification which can describe the details of how to interact with this complex property (based on either the names of the URI variables or using the semantic annotations provided in the above example, see w3c/wot-discovery#144). A consumer which didn't implement that spec would have no chance of figuring out what all those URI variables are for.

Suggesting that consumers differentiate between forms based on URI variables assumes that the consumer has prior knowledge of the device and is expecting a particular URI variable name, which will not be the case for Thing Descriptions in general. It might be possible for a consumer to generate a very generic user interface for such a device (e.g. with a separate HTML form for each Form, with text boxes which accept a string labelled by variable name or title if provided, which can be mapped onto the URI variables). But for a non-human consumer of the API it would be essential to use semantic annotations which denote conformance to a capability schema, defined in an external common schema repository (like iotschema.org).

I therefore suggest that the recommendation should be to use semantic annotations to help consumers differentiate between different forms for the same interaction affordance, given developers are free to use whatever URI variable names they like in forms.

@relu91
Copy link
Member Author

relu91 commented Mar 30, 2021

The Directory Service API is a bit of a special case because we have a concrete specification which can describe the details of how to interact with this complex property (based on either the names of the URI variables or using the semantic annotations provided in the above example, see w3c/wot-discovery#144). A consumer which didn't implement that spec would have no chance of figuring out what all those URI variables are for.

Yes, that's why I opened this issue, with TDD we can describe the intended behavior in prose, but not for a generic TD (not in the current spec at least).

I therefore suggest that the recommendation should be to use semantic annotations to help consumers differentiate between different forms for the same interaction affordance, given developers are free to use whatever URI variable names they like in forms.

Yeah, semantic annotations would help but they kinda work for a specific use case (i.e., the consumer knows that the form tagged with myformtype needs myvar as a convention). I'd rather have a generic mechanism, maybe again exploiting the @type keyword? ( semantically speaking does not really make sense):

{
  properties: {
     "things":  {
           "@type": "ThingListProperty",
            "uriVariables": {
                "id": {
                    "@type": "ThingID",
                    "type": "string",
                    "format": "iri-reference"
                },
                "jsonpath": {
                    "@type": "JSONPathExpression",
                    "type": "string"
                }
            },
            "forms": [
                {
                    "href": "/things/{id}"
                },
                {
                    "href": "/things?jsonpath={jsonpath}",
                     "@type": "JSONPathExpression", // <-- I don't like it at all
                     "useVariables": "JSONPathExpression" // or again using a field to indicate the association
                }
            ]
        }
  }
}

Still, all of this feels pretty hackish and I don't have a better proposal rather than what @egekorkan is proposing OR discouraging people to use forms that have different purposes in the same affordance -> just split your affordances.

@benfrancis
Copy link
Member

OR discouraging people to use forms that have different purposes in the same affordance -> just split your affordances.

This is probably good advice in general.

The reason we combined these different interactions in the Directory Service API is because the property represents a collection of resources, and there's no obvious way to model a collection in a Thing Description (we have the same problem with action queues, where we're having to invent a whole new set of vocabulary in #302).

@mmccool
Copy link
Contributor

mmccool commented Apr 1, 2021

OR we could just go back to using different interactions (with different URLs, making them easy to distinguish), and make queries actions. This is consistent with input and output data models being different, and anyway we have to separate out the SPARQL endpoint for reasons, and making the "modularity" consistent for different query types would be nicer.

In general, assuming a "consumer" is smart enough to "figure things out" concerns me. Why make things hard on the implementor?

@benfrancis
Copy link
Member

@mmccool wrote:

we could just go back to using different interactions (with different URLs, making them easy to distinguish), and make queries actions.

Are you of the opinion that it's good practice for actions to be used in cases where state is not being modified? It's still not clear from the specification when it's appropriate to use an action vs. a property (see #1020). I suggest we need a consensus on the best practice there, before specifying a normative example Thing Description (or Thing Model) which uses actions for read operations.

But regardless, this issue is not specifically about the Directory Service API in the discovery specification, it's about Thing Descriptions in general. There's also currently no guidance about interactions providing multiple forms which differ only by the URI variables being used. Solving only for the Directory Service API is dodging the more general issue.

In the general case (and in the specific case of the Directory Service API) I suggest the best practice should be to provide the consumer with semantic annotations on URI variable definitions which describe their semantic meaning (using an externally defined schema), because there's not enough information in the Thing Description alone to know how to use them.

In general, assuming a "consumer" is smart enough to "figure things out" concerns me. Why make things hard on the implementor?

FWIW this is the argument I've been making about declarative protocol bindings in Thing Descriptions all along and is why there's a need for concrete APIs defined in profiles, and capability schemas for domain specific metadata. This is a general problem, not something specific to the Directory Service API where things are actually already easier since there is a concrete specification.

@benfrancis
Copy link
Member

@relu91 wrote:

semantic annotations would help but they kinda work for a specific use case (i.e., the consumer knows that the form tagged with myformtype needs myvar as a convention). I'd rather have a generic mechanism, maybe again exploiting the @type keyword?

I would have thought that in this example, adding the "@type": "JSONPathExpression" annotation to the URI variable alone should be enough information, if the schema can then define that a ThingListProperty may have a form which accepts a JSONPathExpression as a URI variable in order to filter the output. The former tells the consumer which property to use to fetch a list of things and the latter tells it which URI variable to use to filter the output using a JSONPath expression.

Or am I missing something?

@egekorkan
Copy link
Contributor

@mmccool wrote:

This is consistent with input and output data models being different, and anyway

I think this is not the correct way to find mapping for an interaction. We should first think of the meaning of the interaction before thinking of how to represent it in a TD. I understand why you went for that direction, I used to like having outputData in properties (https://www.w3.org/TR/2017/WD-wot-thing-description-20170914/#property). It would be a breaking change but I would like to have input and output for properties which would solve this problem without breaking the meaning behind what an action is.

@egekorkan egekorkan added the Needs discussion more discussion is needed before getting to a solution label Oct 26, 2021
@egekorkan egekorkan added Forms Topics related to the forms container Defer to TD 2.0 labels Nov 23, 2023
@lu-zero lu-zero added the Has Use Case Potential The use case can be extracted and explained label Jan 26, 2024
@lu-zero
Copy link
Contributor

lu-zero commented Jan 26, 2024

This is another item for the DataMapping use-case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Defer to TD 2.0 Forms Topics related to the forms container Has Use Case Potential The use case can be extracted and explained Needs discussion more discussion is needed before getting to a solution
Projects
None yet
Development

No branches or pull requests

5 participants