- From: Kevin Swiber <kswiber@gmail.com>
- Date: Sun, 26 Jan 2014 20:04:31 +0100
- To: <public-hydra@w3.org>
- Message-ID: <000601cf1ac9$7482edc0$5d88c940$@com>
On Fri, Jan 24, 2014 at 8:30 AM, Markus Lanthaler <markus.lanthaler@gmx.net> wrote: On Thursday, January 23, 2014 9:09 PM, James Langley wrote: > Hydra gives us some nice features from a testing perspective - the > "returns" feature allows us to validate our API output automatically, > and we can re-use the same validation to apply to client-supplied data > for the "expects" side of things. It also seems that we can use the > same Hydra context as both our test blueprint and our developer > documentation, which is nice. Right, that's one of the unique selling points of Hydra I would say. I discussed that in detail in the "Model Your Application Domain, Not Your JSON Structures" paper [3]. I haven't read the paper yet, but the title sounds exactly like what I try to push in API design. I'm looking forward to the read. > It also seems that we can pass better semantics back to the clients > (to support i18n, l10n, and accessibility issues) than Siren allows. Yep, you get that more or less for free. Can you explain Hydra's benefit here? Admittedly, I haven't had to deal with i18n or l10n support. > (Because you don't seem to be able to assign a Siren Class to a Siren > Property, only to an Entity.) I plan to raise that on the Siren Google > Group later. You mean defining the "range" of a property? I thought that's possible but after re-checking the documentation I see it isn't. Apparently field types are limited to the input types specified by HTML5 [4-5]. Confirming this is correct. I'll go into more depth on the Siren list. > Where Siren seems to have an advantage is where we want the API to > change behaviour at runtime depending on the current server state, > i.e. a Class should be POSTable sometimes but not alway;, That's something we discussed in the context of authorization in the past, see ISSUE-7 [6]. The general approach would be to either define a property or a class that you include/exclude based on the resource state. Something like { "@id": "just-an-entity", "@type": [ "BlogPost", "PublishedBlogPost" ], "comments": "just-an-entity/comments" } In this case, the operations that are supported on all posts are associated to the "BlogPost" class. The operations only applicable to published posts are associated to the "PublishedBlogPost" class. Similarly, the "comments" property is just included on posts that can be commented on. I see that a lot of people run into this question, I've thus created ISSUE-23 [7] so that we don't forget to explicitly mention it in the spec. > or a POST may return one Class in some circumstances, and another > Class at other times (and the two Classes are not both semantically > subclasses of the same super Class). A static Hydra context doesn't > allow this. Do you need to document the circumstances under which each class is returned or is it enough to know that you may get different responses? Depending on whether you are willing to use other vocabularies or not, you might be able to describe that using OWL. You could create a union class [8]: { "@context": { "owl": "http://www.w3.org/2002/07/owl# <http://www.w3.org/2002/07/owl> ", "owl:unionOf": { "@type": "@id" } }, "@id": "People", "@type": "owl:Class", "owl:unionOf": [ "Man", "Woman" ] } and use it in "returns". Depending on what we decide to do with multiple values of "returns" and "expects" (are requests/responses instances of all classes or just of at least one class; ISSUE-22 [9]) > (We have been thinking about serving different Hydra contexts at > different times to get round this, but I'm not convinced taht's a > god way to go.) In most cases I agree it isn't a good way to address these issues. One reasonable exception is if the operations depend purely on the authentication of the user. In such a case I would say it makes sense to dynamically serve different contexts and either serve them from different URLs or include a Vary: Authorization header (or something similar) to avoid caching problems. > And because of the lack of an upfront API document, I suspect Siren > client developers are more likely to code generic clients that can > cope with any Siren response, whereas a Hydra client developer might > code a client specific to our Context. That's a valid concern. I deliberately left out a mechanism to describe target URLs in a Hydra description to avoid that. So, in any case, a developer would need to find the URL to POST to by inspecting responses he gets. It's then only a very small step to retrieve and parse the Hydra description dynamically as well. But you are right in principle. It should, however, also be noted that you don't have to use a separate Hydra description at all. You can also embed operations directly into responses as Siren does. See example 6 in the spec [10]: { "@context": "http://www.w3.org/ns/hydra/context.jsonld", "@id": "/an-issue", "title": "Do not rely on upfront API document :-)", "description": "This issue can be deleted with an HTTP DELETE request", "operations": [ { "@type": "DeleteResourceOperation", "method": "DELETE", "title": "Delete this issue" } ] } The disadvantage of doing so is obviously an increased overhead. Typically, in Web APIs responses don't vary much and thus it makes sense (IMO, anyway) to move those descriptions into a separate document that can be cached for a *long* time. Btw. please don't conflate a JSON-LD context (which maps JSON elements to URLs) with a Hydra description (which describes your service). Cheers, Markus [1] https://github.com/lanthaler/JsonLD [2] https://github.com/jsonld-java/jsonld-java [3] http://m.lanthi.com/wsrest2013-paper [4] https://github.com/kevinswiber/siren?source=c#type-1 [5] http://www.w3.org/TR/html5/forms.html#attr-input-type-keywords [6] https://github.com/HydraCG/Specifications/issues/7 [7] https://github.com/HydraCG/Specifications/issues/23 [8] http://www.w3.org/TR/owl2-syntax/#Union_of_Class_Expressions [9] https://github.com/HydraCG/Specifications/issues/22 [10] http://www.hydra-cg.com/spec/latest/core/#adding-affordances-to-representati ons -- Markus Lanthaler @markuslanthaler -- Kevin Swiber Projects: https://github.com/kevinswiber Twitter: @kevinswiber
Received on Sunday, 26 January 2014 19:05:04 UTC