W3C home > Mailing lists > Public > public-hydra@w3.org > November 2013

Re: Schema.org Actions - an update and call for review

From: Sam Goto <goto@google.com>
Date: Tue, 12 Nov 2013 14:12:56 -0800
Message-ID: <CAMtUnc7OQsRDp8tF-v6yT01D=YTKNmSNaPwu_=HbE5H9wsmWUw@mail.gmail.com>
To: Markus Lanthaler <markus.lanthaler@gmx.net>
Cc: public-hydra@w3.org, W3C Web Schemas Task Force <public-vocabs@w3.org>
On Mon, Oct 21, 2013 at 2:35 AM, Markus Lanthaler
<markus.lanthaler@gmx.net>wrote:

> On Saturday, October 19, 2013 3:19 AM, Sam Goto wrote:
> > > > For example, netflix can stream (http://schema.org/WatchAction)
> movies
> > > > (http://schema.org/Movie), but not *any* movie: it can stream a
> specific
> > > > set of movies that are in their *inventory* of streamable movies
> (e.g.
> > > > movies that in theatres right now are *not* in their inventory,
> movies
> > > > that can only be rented via DVDs either, etc).
> > >
> > > If there's a large number of instances which all support the same
> > > operations, it makes sense to create a separate class to communicate
> that
> > > information to the client. In the example above, that class could,
> e.g.,
> be
> > > called StreamableMovie. The WatchAction can then simply be attached to
> that
> > > class. When talking to programmers without Semantic Web background I
> > > typically explain that in terms of interfaces an instance implements or
> > > inheritance similar to what they know from their object oriented
> programming
> > > languages.
> >
> > Although this is in the right direction, we found it to be slightly
> trickier
> > than that. One example is that Netflix and Hulu may have StreamableMovie
> on
> > their inventories, *but* Netflix/Hulu may only play the StreamableMovies
> on
> > *their* inventories.
> >
> > So, you need to get deeper into the constraint and add that Netflix can
> play
> > movies that (a) needs to be a StreamableMovie but as well as (b) it needs
> to
> > have url = "netflix.com" for instance.
>
> So basically you are saying you get the information about the movie
> somewhere else, right? In my description I was assuming you are browsing
> through Netflix' API and get the StreamableMovies there. Netflix obviously
> know whether their movie is streamable or not. I think we are talking about
> slightly different use cases or at least solutions.
>

Possibly. Most service providers expose their inventory via
schema.orgmarkup on their webpages, here is one example:

http://movies.netflix.com/Movie/The-Pursuit-of-Happyness/70044605

One way or another, I'd like to create a bidirectional bound between these
Movie instances and the Netflix service of streaming movies.

The instance to service direction is trivial. Like you said, we can add a
"operation" property to instances that point to the services. This
direction solves a wide variety of problems and that's great.

The service to instances direction is a bit more complicated, but still
useful. That is: how do you make a service instance point to a set of movie
instances (i.e. movie instances that the service can stream)?


>
> > One direction we are exploring (which adds a *lot* of complexity), is
> having
> > some sort of constraint/restriction Type that could express these
> > constraints. Here is one example of such a thing.
>
> Hmmm... this may work very well within a *single* API but I can't see how
> such an approach should work across the Web.
>

In my experience, the most common constraint that appears is to be able to
delimiter an inventory. That is: a "Movie" is too broad, sometimes you need
to define "which specific Movies" you can act on (substitute "Movies" with
"Songs you can listen to on my service", "Products you can by on my grocery
store", etc).


>
>
> > > If the operations/actions that the various resources of a Web API offer
> > > widely, it often makes more sense to attach the operations directly to
> the
> > > instance instead of binding it to a class. Hydra supports that via its
> > > "operations" property:
> > >
> > > {
> > >   "@context": "http://purl.org/hydra/core/context.jsonld",
> > >   "@id": "/a-movie",
> > >   "title": "A streamable movie",
> > >   "operations": [
> > >     {
> > >       "@type": "http://schema.org/WatchAction",
> > >       "method": ...
> > >       ...
> > >     }
> > >   ]
> > > }
> >
> > Yep, that's another direction we are exploring. We are exploring adding
> one
> > property to http://schema.org/Thing called potentialAction (or
> operation,
> > exact name TBD) that does the mapping to the action that can be taken on
> a
> > specific Thing instance.
> >
> > Here is where we explored this idea.
> >
> > Basically, instead of expressing the map of action -> entities, we
> instead
> > ask publishers/developers to expose the reverse map of entity -> actions
> and
> > we then crawl and build the reverse index.
>
> This sounds as you would like to build something similar to actions in
> GMail, is that correct? Or why else do you suggest to "prefer" actions over
> entities?
>

Apologies if I'm not articulating myself clearly, some of this isn't
entirely well formed yet :) Let me try to be more concrete using an example:

Take for example the following entities:

(1) Hertz is an AutoRental <http://schema.org/AutoRental> is a business
that has a service which is to rent
RentalCar<https://developers.google.com/schemas/reference/types/RentalCar>
s
(2) Honda Civic is a
RentalCar<https://developers.google.com/schemas/reference/types/RentalCar>
that
is rented by an AutoRental <http://schema.org/AutoRental>, Hertz.

This specific Honda Civic (a) is on Hert'z inventory (b).

(a) is what i'm referring to the entity -> action problem, which is simple.
(b) is what's i'm referring to the service -> entities problem, which
depends on modelling the service's inventory.

If you extend (b) to a real life example, you'll get to the fact that Hertz
can actually rent *a lot* of RentalCars but not *all* RentalCars that can
ever exist (e.g. it cannot rent a RentalCar that is in Budget's inventory).

The problem is: how do you scale (b) to represent a large (and possibly
dynamic) set of RentalCars?

(a)


   1. {
   2.   "@context": "http://schema.org",
   3.   "@type": "RentalCar",
   4.   "@id": "1234"
   5.   "model": "Honda Civic"
   6.   "operation": {
   7.     "@type": "RentAction",
   8.   "actionHandler": {
   9.     "@type": "ActionHandler",
   10.     "url": "http://www.hertz.com/rent"
   11.   }
   12.   },
   13. }
   14.

(b)


   1. {
   2.   "@context": "http://schema.org",
   3.   "@type": "AutoRental",
   4.   "name": "Hertz"
   5.   "operation": {
   6.     "@type": "RentAction",
   7.   "actionHandler": {
   8.     "@type": "ActionHandler",
   9.     "url": "http://www.hertz.com/rent"
   10.   "object": {
   11.     "@type": "RentalCar",
   12.     "@id": "1234"
   13.   }
   14.   }
   15.   },
   16. }
   17.


>
> > Here is an example:
> >
> > <script type="application/ld+json">
> > {
> >  "@context": "http://schema.org",
> >  "@type": "Movie",
> >   "url": "http://movies.netflix.com/WiMovie/Like_Crazy/70167118",
> > "operation": {
> >  "@type": "WatchAction"
> >  "status": "proposed",
> >  "handler" : {
> >     "@type": "WebPageHandler",
> >     "url":
> "
> http://movies.netflix.com/WiPlayer?movieid=70167118&trkid=1464504&t=Like+Cr
> azy",
> >    "method": "GET",
> >  }
> > }
> > </script>
>
> Wouldn't this specific example be much simpler if you would introduce a
> specialized property as I suggested in my last mail [1]? Something like:
>
> {
>   "@context": "http://schema.org",
>   "@id": "http://movies.example.com/Like_Crazy",
>   "@type": "Movie",
>   "stream": [
>     "http://movies.netflix.com/WiPlayer?movieid=70167118&trkid=1464504",
>     "http://hulu.com/89089409840650440",
>   ]
> }


> It would of course also be possible to use objects instead of just URLs in
> "stream" to convey more information (e.g. price, provider etc.):
>
>   {
>     "@id: "http://hulu.com/89089409840650440",
>     "provider": "http://hulu.com",
>     "subscriptionReqired": true,
>     ...
>   }
>

Right. "provider" would certainly satisfy my criteria.

The modelling problem that we are facing is: how do you express "all movies
whose 'provider'=hulu"? That is, how do you programatically bind "hulu as a
service" to "all movies where hulu is set as a provider"?


>
>
> > I think you got the general idea of the options we are exploring.
> >
> > I think the entity -> actions mapping is fairly clear and solves a huge
> > number of problems.
>
> Agreed
>
>
> > We still think we need the action -> entities mapping too, we'd love any
> > input you may have in that area. We explored things like resource shapes,
> > sparql ask queries and prototype languages.
>
> Hmm... since you were speaking about crawling and creating inverse indexes
> before, why do you think you need it? Let's try to talk about more concrete
> use cases. I suspect one use case you might be interested to address is
> that
> a user gets an email about an event. You would then like to create a user
> interface which allows the user to book a ticket for that event. So you
> need
> to find APIs (actions) that allow you to do that. You could either try to
> describe the actions as accurate as possible (the action accepts Events,
> that are in a specific region, maybe organized by some specific organizer
> etc.) or you try to find the corresponding event entity by crawling the
> API.
> I think the latter is much simpler to achieve.
>
> Say the user gets a mail about Lady Gaga's concert in two weeks. You would
> then need to have an index of APIs that allow you to book tickets for that
> event. You already crawl event sites, why can't you just do the same for
> APIs? It's then a matter of ensuring that the found events match the one
> the
> user looks for. You then have a lot of entries in the following shape:
>
> {
>   "@id": "http://example.com/event4680",
>   "@type": "Event",
>   "name": "Lady Gaga live in concert",
>   ...
>   "offers": [
>     {
>       "@id": "http://example.com/event4680/398",
>       "@type": "Offer",
>       "name": "General Admission Ticket",
>       "price": "89",
>       "priceCurrency": "USD"
>       "operations": {
>         "@type": "BuyAction",
>         "method": "POST",
>         "expects": "http://example.com/vocab/OrderDetails"
>       }
>     },
>     ...
>   ]
> }
>
> Don't you think such an approach would be much simpler and work in 99% of
> the cases?
>
>
> > Here are a few examples (none of which we are particularly excited
> about):
> >
> > Resource shapes:
> >
> > <script type="application/ld+json">
> > {
> >  "@context": "http://schema.org",
> >  "@type": "WatchAction"
> >  "status": "proposed",
> >  "object/restriction" : {
> >    "@type": "DataTypeRestriction",
> >    "describes": "http://schema.org/Movie",
> >    "property" : {
> >      "property": "http://schema.org/url",
> >      "pattern": "http://movies.netflix.com/Movie/",
> >    }
> >    "property" : {
> >      "property": "http://schema.org/streameable",
> >      "allowedValue": "true",
> >    }
> >  },
> >  "handler" : {
> >    "@type": "ActionHandler",
> >    "url": "http://www.netflix.com/watch",
> >  }
> > }
> > </script>
> >
> >
> > SPARQL
> >
> >
> > <script type="application/ld+json">
> > {
> >  "@context": "http://schema.org",
> >  "@id": "SFRestaurant"
> >  "@type": "Type",
> >  "name": "SF Restaurant",
> >  "restriction": {
> >      "@type": "DatatypeRestriction" {
> >        "sparql": "SELECT ?r WHERE {?r <http://schema.org/address>
> >         [<http://schema.org/addressLocality> 'SF']}"
> >      }
> >    }
> > }
> > </script>
>
> Again, while I think these might be a great solution for internal APIs, I
> don't think they would work (and scale) if used across the whole Web. In
> such a case, I think a radically simpler approach such as Hydra's expects
> mechanism gives you almost the same the functionality with considerably
> less
> complexity. I believe it's too complex (close to impossible) to express the
> restrictions in a generic manner since in most cases it not only depends on
> the entity-action relationship but also on the relationship between the
> user
> trying to invoke the action and the API publisher offering it. So questions
> like whether the user has a Hulu account.. if so, which one.. where the
> user
> is located etc.
>

Yep, I agree that the service -> entity mapping is a lot more complex, and
I agree that the entity -> operations mapping solves a really huge amount
of problems. I'm still falling short of a killer use case that requires the
service -> entity mapping, but as soon as I get one we can move on this
discussion to a more concrete level.


>
>
> Cheers,
> Markus
>
> [1] http://lists.w3.org/Archives/Public/public-hydra/2013Oct/0025.html
>
>
>
> --
> Markus Lanthaler
> @markuslanthaler
>
>
Received on Tuesday, 12 November 2013 22:13:24 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 6 January 2015 20:29:40 UTC