- From: Sam Goto <goto@google.com>
- Date: Thu, 23 Jan 2014 17:23:54 -0800
- To: Markus Lanthaler <markus.lanthaler@gmx.net>
- Cc: W3C Web Schemas Task Force <public-vocabs@w3.org>, public-hydra@w3.org
- Message-ID: <CAMtUnc5cvdXMxagupT6TDwbEQVvjSd54KfqSBxxHM-ChJ694HA@mail.gmail.com>
On Wed, Nov 27, 2013 at 6:37 AM, Markus Lanthaler <markus.lanthaler@gmx.net>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. > > > > Right. That maps more closely to the API that gmail launched with and it > > also maps better to the use cases we have with indexing <forms>. > > Right, but adding another object in between even if it has nothing else > than > a supportedProperties member wouldn't hurt much IMO. It would also open the > door to, e.g., support binary data. > > > > But most importantly, this doesn't corner us to taking Class in case we > > need to in the future. > > But it makes it more difficult and introduces a mismatch between Schema.org > and Hydra which I would like to avoid. > > > > > 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 in exchange for 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 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 > > Moments: insert > =============== > > ## Request body ## > > In the request body, supply a **Moments resource** with the following > properties: > > Property name | Value | Description | Notes > -------------------------------------------------------------------- > Required Properties > -------------------------------------------------------------------- > target | nested object | The object on which... | > type | string | The Google schema.... | writable > -------------------------------------------------------------------- > Optional Properties > -------------------------------------------------------------------- > startDate | datetime | Time stamp of when... | writable > > > ## Response ## > > If successful, this method returns a **Moments resource** in the > response body. > > Could be translated directly into (omitting range information): > > { > "name": "Moments: insert", > "@type": "Operation", > "method": "POST", > "expects": { > "@id": "#Moments", > "supportedProperties": [ > { > "@id": "#target", > "name": "The object on which...", > "required": true > }, > { > "@id": "#type", > "name": "The Google schema...", > "required": true > } > { > "@id": "#startDate", > "name": "Time stamp of when...", > "required": false > } > ] > }, > "returns": "#Moments" > } > > > > > I think it's important to have something that mimics that. That's why I > > > introduced the supportedProperties property in the first place. If > > > there's no existing class which specifies the supportedProperties you > > > need, you subclass one (or more) and specify them yourself. Then you > > > can easily reuse that new class consistently across your API. > > > > That's certainly a possibility. Most of our existing users (e.g. gmail > > actions, g+ actions, yandex islands) take the entire action as the > > payload/request/parameters, rather than an individual noun/class. > > And nothing would stop them doing so in the future.. regardless of > "expects" > takes a class or not. > > > > I certainly agree that we could eventually find that we'd need to pass > > just nouns/classes, but at the moment we've been fairly happy with the > > transfer of the entire action between parties. > > I'm not proposing to change that -- even though I think it might make a lot > of sense for products such as Actions in GMail which will just accept > certain classes/properties anyway. > > > > 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. 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 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 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. Here is what this http://code.sgo.to/crawler/yaap.html#url=http://code.sgo.to/hotels/123would 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" ] }], "returns": "http://schema.org/ItemList", "actionHandler": [ { "@type": "HttpHandler", "name": "Creates a new reservation for this hotel", "httpMethod": "post", } ] } } } > > Thanks, > 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 Friday, 24 January 2014 01:24:23 UTC