- From: Thad Guidry <thadguidry@gmail.com>
- Date: Tue, 12 Nov 2013 16:44:41 -0600
- To: Sam Goto <goto@google.com>
- Cc: Markus Lanthaler <markus.lanthaler@gmx.net>, public-hydra@w3.org, W3C Web Schemas Task Force <public-vocabs@w3.org>
- Message-ID: <CAChbWaPae5cGDEwRHKDOFGtYz3-8a836LrVodvv+U094xQ+wfA@mail.gmail.com>
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