- From: Sam Goto <goto@google.com>
- Date: Mon, 27 Jan 2014 09:15:58 -0800
- To: Markus Lanthaler <markus.lanthaler@gmx.net>
- Cc: W3C Web Schemas Task Force <public-vocabs@w3.org>, public-hydra@w3.org
- Message-ID: <CAMtUnc6qhCUSU9BF-5EibY1niuxWkDJhYOeXHdMDd7R2_yLR3w@mail.gmail.com>
On Fri, Jan 24, 2014 at 8:47 AM, Markus Lanthaler <markus.lanthaler@gmx.net>wrote: > On Friday, January 24, 2014 2:24 AM, Sam Goto wrote: > >> On Wed, Nov 27, 2013 at 6:37 AM, Markus Lanthaler wrote: > >> On Tuesday, November 26, 2013 7:39 PM, Sam Goto wrote: > >>> On Wed, Nov 20, 2013 at 8:40 AM, Markus Lanthaler wrote: > >>>> Hmm... you changed "expects" to take a SupportedProperty instead of a > >>>> Class which results in a asymmetry with "returns" which still takes a > >>>> Class. > > [...] > > >>>> Furthermore, SupportedProperty has no "property" property anymore but > >>>> you use "name" to specify it - which is a string and could be > anything. > >>> > >>> SupportedProperty extends from Property, so it doesn't need to take > one. > >> > >> This doesn't make any sense to me as it makes it completely impossible > to > >> reuse any of the existing Schema.org properties (or any property in > another > >> vocabulary for that matter). > > > > Got it. So instead of referring to the property via the "name" (e.g. > > "description"), you use URI identifiers instead (e.g. > > http://schema.org/description) which buys you precision > > Exactly > > > in exchange for verbosity? > > Not necessarily. At least not in JSON-LD: > > { > "@context": { > "@vocab": "http://schema.org/", > "property": { "@type": "@vocab" } > }, > "property": "description" > } > > expands to > > { > "http://schema.org/property": { > "@id": "http://schema.org/description" > } > } > > and thus doesn't introduce additional verbosity. > > > >>>>> In most cases a human-readable label to be read in a dynamically > >>>>> generated UI or documentation. > >>>> > >>>> I'm not sure I like this design. The reason is that most developers > >>>> think in terms of (resource) classes. This is pretty apparent even if > >>>> you just look at three arbitrary Web APIs: > >>>> > >>>> Google+: https://developers.google.com/+/api/latest/ > >>> > >>> I am/was actively involved in most of these APIs :) > >> > >> Then your change surprises me even more as the documentation uses > >> exactly the structure I'm proposing. For example (citing [1]): > > > > You are right. I think that thinking in terms of resources (rather than > > RPCs) gets lots of things simplified. Specifically, the following: > > > > - collections: which allows you to do things like (a) searching for > > resources and (b) creating/acting on resources even before they exist > > - resource hopping: moving from one resource to another and performing > > operations in the right context > > - dynamic operations: as resource state changes, operations available in > > them are now made possible to change > > Right. Furthermore, it integrates much better with the architecture of the > Web in general. > > > > Here are a few demos I'm writing to validate this model with a few real > > world use cases that are relevant: > > > > http://code.sgo.to/crawler/yaap.html#url=http://code.sgo.to > > Wow! Cool stuff! Are these documents available somewhere to download? I > mean in the form of a single archive or a Git/SVN/whatever repository? That > would make it simpler for me to go through all the examples. > > The "crawler" part of this demo is here (super messy/hacky, sorry): https://github.com/samuelgoto/samuelgoto.github.io/tree/master/src The "client/service/provider" part of the demo is currently in a private repo, but I'd be happy to share if there is interest. > I know the ActionHandler stuff is there for Android support etc. but > wouldn't it be possible to avoid it (as discussed previously) and thus > eliminate one level of nesting? > I don't think so. There is some extra metadata that is needed to invoke actions on android (e.g. the application package name. without it, any application can filter to catch a specific url pattern<http://developer.android.com/guide/components/intents-filters.html>) and windows (you need things like ms-AppFamilyName, ms-AppId and ms-MinVersion to kick off a native windows app<http://msdn.microsoft.com/en-us/library/ie/hh781489(v=vs.85).aspx> ). This also needs to work with iOS, so I don't think we can avoid action handlers. On a related note, this is quite interesting too: http://appurl.org and I'm really glad to see things like that popping up. > > > [...] > > >>> Most importantly, with "expects" and "returns" being schema.orgproperties > >>> they can evolve incrementally over time to take other types (e.g. > Class), > >>> so hopefully we can cross this bridge when we get to it. > >> > >> I really don't understand the reasons for the deviation of the model > Hydra > >> or (Resource Shapes) follow. Are you concerned about the complexity? I > >> think it makes things much easier to understand a allows reuse which is > >> impossible if a just a set of SupportedProperties is used. > >> > >> Have you had the chance to take a look at [2]? Would love to hear your > >> opinions? > > > > I did, yes, thank you that's super helpful. > > Great > > > > I think SupportedClasses make sense, but I'm still unhappy with > > complexity and verbosity of large API specifications when you get into > > the "nested requirements case" (which gmail is addressing via a "path- > > like" syntax with things like "review.reviewBody" to refer to the > > "reviewBody" property inside "review") ... Take food orders as an > > example: > > > > > http://code.sgo.to/crawler/yaap.html#url=http://code.sgo.to/restaurants/123/orders > > Good point. The question here, I think, is really whether you want to > embrace linked data principles or not. If you do, you are able to define > your classes with their supported properties somewhere and then reference > them from properties by using their URLs. Obviously clients then need to > fetch those documents on the fly (or cache them locally). If you want/need > to define everything inline it becomes trickier. A possibility would be to > create new classes on the fly which flatten these structures but that's not > very elegant either. But honestly, I don't think this nesting is really a > problem. It's quite symmetric and developers are used to these things > already. In HTML, e.g., you create similar nestings all the time (think of > list with sub-lists e.g.) > > > Right. The extra hop might be a deal breaker for a few applications, like gmail actions. I understand your point, I just think that we need to make the simple case simple. > > It ends up with a quite large/verbose/complex set of requirements and > > expectations, and I'm trying to find ways to compress that into > > something cleaner for the simple case. > > > > Here is another example that I explored a bit deeper: > > > > http://code.sgo.to/crawler/yaap.html#url=http://code.sgo.to/hotels/123 > > Nice, concise example (the operation type should be something like > BookAction though, not SearchAction). > In this example, the user is "searching" for an available reservation/room against the "reservations" list attached to a hotel. Once you find one (which you do if you click on the SearchAction), you can ReserveAction an individual LodgingReservation. So, you SearchAction against an ItemList (collection) of LodingReservation. Separately, you ReserveAction/ConfirmAction/CancelAction a LodgingReservation that is available. Does that make sense? > > > > One idea is to take advantage of the fact that most times you want to > > express whether a property is required or not (rather things like > > cardinality, min/max values, etc). For example, if we (a) break down > > http://schema.org/SupportedClass.supportedProperty-ies into > > requiredProperty and optionalProperty and (b) let it take > > http://schema.org/Property (in addition to > > http://schema.org/SupportedProperty, which no longer holds whether the > > property is required or not), it avoids having to instantiate a new > > SupportedProperty. > > > > In the complex case (e.g. requirements on cardinality, min/max values, > > enumerations, etc), requiredProperty and optionalProperty may still > > take a SupportedProperty in case it needs to be more specific. > > How would you know what it is? Go and dereference all of them and check > their types? > schema.org properties can take multiple types. It could potentially take a SupportedProperty (in case you need to be more specific) as well as a Property (in case you don't have any extra requirements). > > > > Here is what this > > http://code.sgo.to/crawler/yaap.html#url=http://code.sgo.to/hotels/123 > > would look like with these constructs: > > > > { > > "@context": "http://schema.org", > > "@type": "Hotel", > > "@id": "http://localhost:5000/hotels/123", > > "name": "Hilton", > > "reservations": { > > "@type": "ItemList", > > "@id": "http://localhost:5000/hotels/123/reservations", > > "operation": { > > "@type": "SearchAction", > > "actionStatus": "proposed", > > "expects": [{ > > "@type": "SupportedClass", > > "subClassOf": "LodgingReservation", > > "requiredProperty": [ > > "http://schema.org/checkInDate", > > "http://schema.org/checkOutDate", > > "http://schema.org/numberOfAdults", > > "http://schema.org/numberOfChildren" > Just sanity checking Markus: is this valid JSON-LD? i.e. is it legal to say that the previous statement [1] corresponds to the following [2] expanded statement? [1] "requiredProperty": [ "http://schema.org/checkInDate",] [2] "requiredProperty": [ { @type: Property, @id: "http://schema.org/checkInDate" } ] > > ] > > }], > > "returns": "http://schema.org/ItemList", > > "actionHandler": [ > > { > > "@type": "HttpHandler", > > "name": "Creates a new reservation for this hotel", > > "httpMethod": "post", > > } > > ] > > } > > } > > } > > Yeah, this looks much cleaner, but you cheated a bit by eliminating the > actionHandler nesting :-) In our latest thinking (which I still need to put down on paper and publish), we think that the "expects" and "returns" constructs should go into the Action-level properties, because it may apply to multiple action handlers (example: if you have an android app as well as a web API, you don't want to repeat yourself what your API looks like). > Furthermore, as soon as you need to add a single property (not just > cardinality but also a *label* or a *description*) you would end up with > exactly the same nesting. Have a look at this variation: > Yep, in that case you'd want to use a SupportedProperty instead. > > { > "@context": "http://schema.org", > "@type": "Hotel", > "@id": "http://localhost:5000/hotels/123", > "name": "Hilton", > "reservations": { > "@type": "ItemList", > "@id": "http://localhost:5000/hotels/123/reservations", > "operations": { > "@type": "BookAction", > "name": "Creates a new reservation for this hotel", > "method": "POST", > "expects": [{ > "@type": "SupportedClass", > "subClassOf": "LodgingReservation", > "supportedProperty": [ > { "property": "checkInDate", "required": true }, > { "property": "checkOutDate", "required": true }, > { "property": "numberOfAdults", "required": true }, > { "property": "numberOfChildren", "required": true } > ] > }], > "returns": "http://schema.org/ItemList" > } > } > } > > How do you find this version? > Does this version require any "automatic-expansion" that you mentioned before? Or is this valid JSON-LD out of the box? > > I removed the HttpHandler in the example. I know you probably need it to > decide whether to invoke the operation directly and showing the user just > the result or open a new browser window. That information could be > expressed as an operation type if needed so, "@type": [ "BookAction", > "WorkflowOperation" }. In lack of a better term I used WorkflowOperation to > express that this specific operation is part of a larger workflow and that > requires a new browser window to be opened so that the user can complete > the remaining steps. > Handlers are not necessarily "workflow" specific. That is, they exist because invoking actions in different platforms is complicated (e.g. this<http://developer.android.com/guide/components/intents-filters.html>is what it takes to invoke on android, and this <http://msdn.microsoft.com/en-us/library/ie/hh781489(v=vs.85).aspx> is how you invoke on windows). > > > Cheers, > Markus > > > >> [1] https://developers.google.com/+/api/latest/moments/insert > >> [2] http://www.hydra-cg.com/spec/latest/schema.org/ > > > -- > Markus Lanthaler > @markuslanthaler > >
Received on Monday, 27 January 2014 17:16:30 UTC