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

Nested structures (supportedProperty) #26

Open
lanthaler opened this issue Feb 3, 2014 · 4 comments
Open

Nested structures (supportedProperty) #26

lanthaler opened this issue Feb 3, 2014 · 4 comments

Comments

@lanthaler
Copy link
Member

Sam Goto raised concerns about the complexity of nested structures. We need to reduce the verbosity of operations expecting nested structures in which some of the properties in nested objects have, e.g., to be marked as required.

Actions in Gmail currently uses property paths to express such things:

<script type="application/ld+json">
{
  "@context": "http://schema.org",
  "@type": "EmailMessage",
  "description": "We hope you enjoyed your meal at Joe's Diner. Please rate your experience.",
  "action": {
    "@type": "ReviewAction",
    "review": {
      "@type": "Review",
      "itemReviewed": {
        "@type": "FoodEstablishment",
        "name": "Joe's Diner"
      },
      "reviewRating": {
        "@type": "Rating",
        "bestRating": "5",
        "worstRating": "1"
      }
    },
    "handler": {
      "@type": "HttpActionHandler",
      "url": "http://reviews.com/review?id=123",
      "requiredProperty": {
        "@type": "Property",
        "name": "review.reviewRating.ratingValue"       <--- PROPERTY PATH
      },
      "method": "http://schema.org/HttpRequestMethod/POST"
    }
  }
}
</script>
@lanthaler
Copy link
Member Author

_Markus' reply to Sam's mail:_

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 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.

@gkellogg
Copy link

gkellogg commented Feb 3, 2014

This, of course, invokes OWL restrictions for doing similar things; if Hydra is ultimately intended to be a W3C recommendation, then working smoothly with existing technologies would seem to make sense. However, Hydra also seems intended to influence schema.org, which is already inconsistent with OWL (e.g. rangeIncludes/domainIncludes), and so some approach that is more native or web-friendly also is worth pursuing.

Regarding property paths, @lanthaler's suggestion takes advantage of common JavaScript object navigation, but this does tie it vary closely to JSON. IMO, we should be wary of this and consider concepts which are not so bound to a format. For example, SPARQL property paths also provide a way of navigating through such object structures; this might be review/reviewRating/ratingValue. This approach could also allow for relative patching using ^.

@lanthaler
Copy link
Member Author

This, of course, invokes OWL restrictions for doing similar things;

Gregg, would you mind explaining this on the mailing list (I would prefer to keep the discussion there as more people will be able to follow it)?

Regarding property paths, @lanthaler's suggestion takes advantage of
common JavaScript object navigation, but this does tie it vary closely
to JSON. IMO, we should be wary of this and consider concepts which are
not so bound to a format.

Just for the record: this wasn't my suggestion. It is what Gmail uses today:

https://developers.google.com/gmail/actions/reference/review-action

I'm myself very concerned about this.

@lanthaler
Copy link
Member Author

PROPOSAL: See proposal of ISSUE #37, it addresses this issue as well

dschulten added a commit to dschulten/hydra-java that referenced this issue Dec 31, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants