- 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