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

And where Sam means :

(a) the specific Honda Civic within Hertz's rental inventory that would be
directly associated to a VIN number ( a unique identifier for automobiles
in the last 50 years )
http://en.wikipedia.org/wiki/Vehicle_Identification_Number

(a) can only be rented out to a single person during a given
timeframe...blah blah, and a host of other rules and unique actions at a
specific instance level such as this.

Honda Civic being a product model with many (a) instances around the world,
including all the rental car companies.

HTH,



On Tue, Nov 12, 2013 at 4:12 PM, Sam Goto <goto@google.com> wrote:

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


-- 
-Thad
+ThadGuidry <https://www.google.com/+ThadGuidry>
Thad on LinkedIn <http://www.linkedin.com/in/thadguidry/>

Received on Tuesday, 12 November 2013 22:45:11 UTC