- From: John Walker <john.walker@semaku.com>
- Date: Tue, 7 Oct 2014 22:07:39 +0200 (CEST)
- To: "public-hydra@w3.org" <public-hydra@w3.org>, Dietrich Schulten <ds@escalon.de>
- Message-ID: <100013880.205957.1412712459604.open-xchange@oxweb05.eigbox.net>
Hi Dietrich, Some comments on the RDF side of things inline. John > On October 7, 2014 at 9:03 AM Dietrich Schulten <ds@escalon.de> wrote: > > > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > Hi, > > I'm toying with the event API demo > http://bit.ly/hydra-console-event-api. I want to share a few > observations and ideas, backed by my experience with designing ReST APIs. > Disclaimer: I have some basic knowledge about rdfs, but my ideas > simply might not work as linked data. > > The meat of the event-api is at > http://www.markus-lanthaler.com/hydra/event-api/vocab. > Observation: the vocab is quite lengthy for a simple use case. 241 > LOC, much of it seems repetitive. > > We are talking about a pretty standard situation: you can POST, PUT > and DELETE to the /events resource. If you POST or PUT, your request > should contain an object that has attributes as defined by > http://schema.org/Event. Only some of them are required, most are not > supported. > Your /events page would be a hydra:Collection of schema:Event 'instances'. As such you would presumably only allow GET and POST methods on the collection. PUT and DELETE would be more suited for use on the schema:Event instances. > My general feeling is: it should not be necessary to maintain such a > large description. Somehow we must leverage convention over > configuration and the existing vocabs in such a way that I only need > to define things I cannot take for granted. And we must be more DRY. > > I want to keep my context short so I can embed it. With Javascript > clients in mind, I'd rather have everything in the resource that is > needed to work with it. > > In the following I want to discuss the EntryPoint, the EventCollection > and the Event. > > - ------------------------ > > In my ideal world this could be the EntryPoint: > > { > "@context": { > "@vocab" : "http://schema.org", > "hydra" : "http://www.w3.org/ns/hydra/core#" > }, > "@id": "http://www.markus-lanthaler.com/hydra/event-api/", > "@type": "hydra:EntryPoint", > "event": { > "@id": "http://www.markus-lanthaler.com/hydra/event-api/events/", > "@type": "hydra:Link" > } > } > (I prefer full urls because they work in stock rest clients.) > > Short, no external context, no site-specific vocab. > The question is, is this valid from a Linked Data point of view? > Here you are saying the resource http://www.markus-lanthaler.com/hydra/event-api/events/ has rdf:type hydra:Link, which does not seem correct. I would expect that resource to have rdf:type hydra:Collection instead. > Note that the event property is now http://schema.org/event, no longer > EventCollection. > By doing this I would expect the thing you link to with schema:event is a schema:Event, but seems that you link to a hydra:Collection of events. > First of all, http://schema.org/event appears on Place, Organization > and a number of Actions. In RDF, are we free to use schema:event on an > EntryPoint? Can I state > > "schema:event rdfs:domain hydra:EntryPoint" > > somewhere in my context to allow this usage? And do I have to, don't I > say that already by using schema:event on a hydra:EntryPoint? In the > json world no "static typing" exists that would prevent me from adding > any attribute. > This is not wrong per-se, but would entail that all resources this property is used on have rdf:type hydra:EntryPoint which does not seem correct. If you used the sematically weaker schema:domainIncludes property, it would be OK from an RDF perspective. However I'd have to question if/why you would want to link from an API entry point to an event, unless you have conferences about an API of course :) > An alternative could be not to use hydra:EntryPoint, but Organization > or Place as @type of the index resource. Now that I think of it, that > also makes a lot of sense. Probably the owner of the events wants to > tell something about himself on the index resource anyway. But the > question remains: may we attach event to EntryPoint at all? > Indeed linking direct from an Organization or Place to an associated Event make perfect sense. The idea here is to link the list/collection of all registered events to the EntryPoint, not a specific Event instance. > Second: Assuming that we are allowed to use http://schema.org/event: > Values of > schema:event are expected to be of type Event, not of type @id. It > would be easy to program clients so that they understand the > difference and transparently resolve links for data. But does RDF > allow that? Is it correct to use a link to events instead of embedding > the events themselves? If not, can Hydra introduce such a convention? > Or can I at least redefine > > "schema:event rdfs:range jsonld:@id" > > somewhere in my @context? > Suggest to go re-read the JSON-LD spec as it seems you misinterpret how @id is used. In short: yes values of schema:event are expected to have rdf:type schema:Event. @id is just a way to define the URI of the resource being linked to, not to give it a type. > - ----------------------- > > On to the EventCollection. My wishful-thinking EventCollection: > > { > "@context": { > "@vocab": "http://schema.org", > "hydra": "http://www.w3.org/ns/hydra/core#" > }, > "@id": "http://www.markus-lanthaler.com/hydra/event-api/events/", > "@type": "hydra:Collection", > "hydra:member": [ > { > "@id": "http://www.markus-lanthaler.com/hydra/event-api/events/1", > "@type" : "hydra:Link" > }, > { > "@id": "http://www.markus-lanthaler.com/hydra/event-api/events/2", > "@type" : "hydra:Link" > } > ], > "hydra:operation": [ > { > "method": "hydra:CreateResourceOperation", > "hydra:supportedProperty" : [ > "name", > "description", > "startDate", > "endDate", > { > "property": "performer", > "required" : false, > "hydra:supportedProperty" : [ > "name" > ] > } > ] > } > ] > } > I would expect the @type of the members in the collection to be schema:Event rather than hydra:Link. > I assumed that we could have several conventions here. > > 1. It is usually not necessary to know the type of the collection > members in order to create them, since the properties we send are by > definition in the domain of a Thing, e.g. Event. > Therefore I simply used hydra:Collection. > Maybe Collection could have a "hydra:of" Property so that one could say > "@type": { > "@id": "hydra:Collection", > "hydra:of" : "Event" > } > rather than defining a custom class. > But right now I do not see the need for a hydra:of or for typed > collections. Well, I guess there *is* a reason why you introduced the > EventCollection :) Could you explain? > The way I think of it is that the EventCollection class is a more specialized subtype of hydra:Collection. Then we can define additional things about instances of that class that do not apply to the more generic hydra:Collection. > 2. The usual case is that an operation is supported when the resource > comes with the appropriate affordance. Mostly it is not something that > is always supported, since that does not depend on the Class, but on > the usage context. E.g. posting a new Event is probably not supported > if you do not have sufficient rights to do so. The server simply does > not include it if it is not supported. I can hardly imagine cases > where a state-changing operation is *always* supported on a resource. > Hence I put the operation into the resource, not in the documentation. > > 3. It is usually only necessary to list the names of supported > properties for an operation, so instead of saying "property": "xxx" > many times I just listed the property names. > I assumed that by convention a supported property could be > automatically required and read/writable, in a similar way how > http://schema.org/docs/actions.html defines defaults for > PropertyValueSpecification. Is it possible to define default values in > linked data in case a property is absent? > The description should be the one from the source vocab, here > schema.org, so I can > leave it out normally. Note however the use of supportedProperty on > the optional, nested "performer" property. > > 4. There is no need to describe the meaning of status codes in the > resource. I am strongly against overriding the meaning of existing or > defining custom HTTP status codes anyway :) The body of an error > response is the place to give hints how to resolve a problem, and it > should probably follow > http://tools.ietf.org/html/draft-ietf-appsawg-http-problem. Could > hydra:Error be redefined in such a way that a json-ld client accepting > ld+json could by convention get the below error response (with the > standard properties type, title, status, detail, instance and two > extension properties)? > > HTTP/1.1 403 Forbidden > Content-Type: application/problem+json > Content-Language: en > > { > "@context": > { > "@vocab" : "http://www.w3.org/ns/hydra/core#", > "balance" : "http://bank.example.com#balance", > "accounts" : "http://bank.example.com#accounts" > } > "@type": "Error", > "type": "http://example.com/probs/out-of-credit", > "title": "You do not have enough credit.", > "status": 403, > "detail": "Your current balance is 30, but that costs 50.", > "instance": "http://example.net/account/12345/msgs/abc", > "balance": 30, > "accounts": ["http://example.net/account/12345", > "http://example.net/account/67890"] > } > > - ------------------------ > > Up next, Event: > > { > "@context": { > "@vocab": "http://schema.org", > "hydra": "http://www.w3.org/ns/hydra/core#" > }, > "@id": "http://www.markus-lanthaler.com/hydra/event-api/events/1", > "@type": "Event", > "name": "Walk off the Earth - REVO tour", > "description": "Live in concert", > "startDate": "2014-06-14T20:00:00Z", > "endDate": "2004-06-14T23:34:30Z" > "hydra:operation": [ > {"hydra:method": "DELETE"}, > { > "hydra:method": "PUT", > "hydra:supportedProperty" : [ > "name", > "description", > "startDate", > "endDate", > { > "property": "performer", > "required" : false, > "hydra:supportedProperty" : [ > "name" > ] > } > ] > } > ] > } > > Since I have sufficient rights, I can delete and replace the event. > When I replace an Event, I must send the same data as for a creation. > > Clearly our operations overlap with http://schema.org/Action. > I tried to add a schema:ReviewAction onto the Event above, but I ran > into several problems. That is worth a different discussion, however. > > - ------------------------ > > Conclusion: > > In my opinion, this should be all I need to say for the simple CRUD > use case under discussion. But I guess there are some pitfalls I fell > into. > > I guess the event-api as it is today tries to solve a slightly > different problem, maybe to keep the > json resource as terse as possible. I see that quite relaxed, my idea > is, if you request application/json instead of ld+json, then the > server returns a response as terse as can be. > > Best regards, > Dietrich Schulten > > - -- > Dietrich Schulten > Escalon System-Entwicklung > Bubenhalde 10 > 74199 Untergruppenbach > -----BEGIN PGP SIGNATURE----- > Version: GnuPG v2.0.22 (MingW32) > > iEYEARECAAYFAlQzkC0ACgkQuKLNitGfiZOhzwCfSPI+oPw96kuFz4XAUFHdqntZ > b5AAnj3jlPv8PoNP6k/WwR4aNZ4oq2H0 > =Zguh > -----END PGP SIGNATURE----- >
Received on Tuesday, 7 October 2014 20:28:05 UTC