- From: Dietrich Schulten <ds@escalon.de>
- Date: Tue, 07 Oct 2014 09:03:09 +0200
- To: "public-hydra@w3.org" <public-hydra@w3.org>
-----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. 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? Note that the event property is now http://schema.org/event, no longer EventCollection. 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. 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? 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? - ----------------------- 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 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? 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 07:03:42 UTC