Re: Nested structures / ISSUE-26 (was: An updated draft of the schema.org/Action proposal)

On Mon, Feb 3, 2014 at 9:03 AM, Markus Lanthaler
<markus.lanthaler@gmx.net>wrote:

> I changed the subject to focus on nested structures in this thread.
>
>
> On Tuesday, January 28, 2014 4:57 PM, Sam Goto wrote:
> > On Tue, Jan 28, 2014 at 6:22 AM, Markus Lanthaler wrote:
> > > On Tuesday, January 28, 2014 6:02 AM, Sam Goto wrote:
> > > >
> > > > Here is another challenge with this approach: how do you set up the
> > > > expectations on the properties of the Action class? That is, most of
> > > > the invocations take more than one parameter and they map to one of
> > > > the Action properties (e.g. RsvpAction takes an "agent" as well as an
> > > > "attendance" -- whether the agent is going or not).
> > >
> > > It depends. If the agent, e.g., is fixed as it is in most cases when
> > > you send an invitation by email I would encode it in the URL the
> > > response is sent to. If it isn't, I would create an RsvpResponse class
> > > defining those two properties as you do below.
> >
> > Right. Agreed that authentication/authorization has different
> > transport mechanisms (e.g. cookies or oauth tokens). That wasn't a
> > great example on second though.
> >
> > Reviews might be a good one. As you are making a review, services take
> > "reviewBody" as well as "ratingValue" (which is nested inside a
> > "reviewRating" property of type "Rating", hence the nested object).
> >
> > https://developers.google.com/gmail/actions/reference/review-action
> >
> [...]
> >
> > > > Markus, have you run into problems describing nested objects on
> > > > "expects" (e.g. a bug needs an author which in turn needs to have at
> a
> > > > minimum an id?)?
> > >
> > > Yeah, I have been thinking about this but wasn't able to find an
> > > elegant solution yet. If you start relying on Linked Data principles,
> > > i.e., dereferenceable URLs to look up definitions (of course all
> > > concepts can be defined in a single document) a lot of these deeply
> > > nested structures go away as you simply reference the various
> > > concepts. In many other cases, it is possible to eliminate the nesting
> > > by creating a new specialized type or by encoding some of the
> > > information in the URL the data is sent to.
> >
> >
> > As I mentioned to you before, we really need a solution to this. A non
> > trivial number of my actions take nested objects and we need to deal
> > with this requirement from day one.
>
> OK, I've raised ISSUE-26 to keep track of this in the context of Hydra
>
>   https://github.com/HydraCG/Specifications/issues/26
>
>
> > Here are a few examples that could inform/help us come up with
> > something better:
> >
> > hotel reservations
> > http://code.sgo.to/crawler/yaap.html#url=http://code.sgo.to/hotels/123
> > events rsvp-ing
> > http://code.sgo.to/crawler/yaap.html#url=http://code.sgo.to/events/123
> > taxistand reservations
> >
> http://code.sgo.to/crawler/yaap.html#url=http://code.sgo.to/taxistands/123/reservations
> > restaurant orders
> >
> http://code.sgo.to/crawler/yaap.html#url=http://code.sgo.to/restaurants/123/orders
> > product reviews
> > http://code.sgo.to/crawler/yaap.html#url=http://code.sgo.to/products/123
>
> Let's use the review example as it is fairly compact. In your examples
> above you currently use something like this (I slightly simplified it and
> added a required: true):
>
>   {
>     ...
>     "operation": {
>       "@type": "ReviewAction",
>       "expects": {
>         "supportedProperty": [
>           {
>             "property": "http://schema.org/reviewBody",
>             "required": true
>           }
>           {
>             "property": "http://schema.org/reviewRating",
>             "required": true
>             "rangeIncludes": {
>               "subClassOf": "Rating",
>               "supportedProperty": {
>                 "property": http://schema.org/ratingValue",
>                 "required": true
>               }
>             }
>           }
>         ]
>       }
>     }
>   }
>
> This describes the following structure:
>
>   http://schema.org/reviewBody - required
>   http://schema.org/reviewRating - required
>       (subClassOf: Rating)
>       http://schema.org/ratingValue - required
>
> So we either have to replicate that nesting or flatten it somehow.
>
> One option we already discussed it is to avoid the class/supportedProperty
> indirection and instead point directly to properties. In this case it
> wouldn't help much as the nested property is nested inside a rangeIncludes.
>
>   {
>     ...
>     "operation": {
>       "@type": "ReviewAction",
>       "expects": [
>         {
>           "property": "http://schema.org/reviewBody",
>           "required": true
>         }
>         {
>           "property": "http://schema.org/reviewRating",
>           "required": true
>           "rangeIncludes": {
>             "subClassOf": "Rating",
>             "supportedProperty": {
>               "property": http://schema.org/ratingValue",
>               "required": true
>             }
>           }
>         }
>       ]
>     }
>   }
>
> Thus, in order to simplify it we probably need to use something else than
> "rangeIncludes". We could perhaps reuse "supportedProperty" but that would
> make the data difficult to understand IMO. In lack of a better name, I used
> "supportedRange" below and allow its value to be either a Property, a
> SupportedProperty or a Class.
>
>
>   {
>     "@context": "http://schema.org",
>     "@id": "http://code.sgo.to/products/123",
>     "@type": "Product",
>     "name": "A product that can be reviewed",
>     "operation": {
>       "@type": "ReviewAction",
>       "expects": [
>         {
>           "property": "http://schema.org/reviewBody",
>           "required": true
>         }
>         {
>           "property": "http://schema.org/reviewRating",
>           "required": true
>           "supportedRange": {
>             "property": http://schema.org/ratingValue",
>             "required": true
>           }
>         }
>       ]
>     }
>   }
>
> This does indeed simplify the description. The nesting corresponds 1:1 to
> the "abstract nesting":
>
>   http://schema.org/reviewBody - required
>   http://schema.org/reviewRating - required
>       http://schema.org/ratingValue - required
>
> In that sense, it's optimal. Now if really necessary, we could try to
> flatten this representation but I don't know how much value that really
> provides. A trivial approach would be to specify the parent (in this case
> specifying the parent property, another option would be to give the
> SupportedProperty an identifier and use a reverse property for
> supportedRange to connect them):
>
>   {
>     "@context": "http://schema.org",
>     "@id": "http://code.sgo.to/products/123",
>     "@type": "Product",
>     "name": "A product that can be reviewed",
>     "operation": {
>       "@type": "ReviewAction",
>       "expects": [
>         {
>           "property": "http://schema.org/reviewBody",
>           "required": true
>         }
>         {
>           "property": "http://schema.org/reviewRating",
>           "required": true
>         },
>         {
>           "property": http://schema.org/ratingValue",
>           "required": true,
>           "parent": "http://schema.org/reviewRating"
>         }
>       ]
>     }
>   }
>
> I find this flattening quite confusing and counterintuitive. If there are
> nested properties, I think it's reasonable to have the same nesting in the
> descriptions thereof.
>
> What do you think about this options Sam?
>

I think that's a reasonable exploration of this approach. Just to keep this
as a fair/comprehensive comparison, lets look into what it would look like
"path-query-language" approach could look like*:

*majorly patterned after
https://developers.google.com/gmail/actions/reference/review-action

  {
    "@context": "http://schema.org",
    "@id": "http://code.sgo.to/products/123",
    "@type": "Product",
    "name": "A product that can be reviewed",
    "operation": {
      "@type": "ReviewAction",
      "requiredProperties": [{
        "path": "reviewBody"
      }, {
        "path": "reviewRating.ratingValue"
      }]
    }
  }

The "contents" of this payload is equivalent to:

  http://schema.org/reviewBody - required
  http://schema.org/reviewRating - required (transitively inferred via a
sub-property being required too)
      http://schema.org/ratingValue - required

Now, you can certainly formalize the path language to something like SPARQL
queries, XPATH/XSLT (yikes, I know) or the likes.


> I have to say that I don't find the example using rangeIncludes too bad
> even though rangeIncludes (in contrast to rdfs:range) might be a bit
> counterintuitive when used with required properties as it suggests that
> these required properties are somehow nevertheless optional as there might
> be other valid ranges as well.
>
>
Right. One of the advantages of SupportedClass is that it allows you to
link to to an external document. Take a look at the contents of this doc
(view:source and search for itemscopes):

http://code.sgo.to/https+++developers.google.com.gmail+actions+reference+review-action.html

And how it can be used inline:

http://code.sgo.to/crawler/yaap.html#url=http://code.sgo.to/products/123

That is, with linked data, the developer's code becomes quite simpler/more
concise (as you expose the expectations in external docs):

  {
    "@context": "http://schema.org",
    "@id": "http://code.sgo.to/products/123",
    "@type": "Product",
    "name": "A product that can be reviewed",
    "operation": {
      "@type": "ReviewAction",
      "expects": [
        {
          "@id": "
http://code.sgo.to/https+++developers.google.com.gmail+actions+reference+review-action.html
",
        }
      ]
    }
  }


>
>
> --
> Markus Lanthaler
> @markuslanthaler
>
>

Received on Friday, 14 February 2014 00:31:32 UTC