- From: Markus Lanthaler <markus.lanthaler@gmx.net>
- Date: Thu, 4 Sep 2014 16:00:20 +0200
- To: <public-hydra@w3.org>
Hi Martijn. On 2 Sep 2014 at 15:15, Martijn Faassen wrote: > I'm still confused about the Hydra spec, but I think such confusion > can only help improve the spec, so here's some more feedback. I've Oh yeah. The feedback from people that haven't been involved too much yet is especially valuable as it becomes increasingly difficult to see the issues newcomers struggle with the more time you spend on this topic. > learned enough to realize I can in some cases blame the draft spec for > my lack of understanding, instead of just my own ignorance and lack of > intelligence. So I've gotten a bit more critical here and there. The > criticism is very much intended to be constructive! Much appreciated! > =the draft spec= > > So Hydra lets you describe a RESTful web service. It builds on JSON-LD. > > =Issue 3= > > The figure in "Hydra at a glance" is not clear enough for me -- I have > no idea what's going on yet starting to read this spec, and this > doesn't really help make things more clear. I think such a figure, if > needed, should move somewhere below, perhaps into an appendix, so that > once concepts are more clear this might help fill in some gaps. OK. What this figure is trying to do, is to give you an overview of the vocabulary that Hydra defines... but of course that doesn't help you if you are not used to using vocabularies in the first place. > =Section 4= > > It says an issue tracker will be used as an example. But while an > issue tracker is used in some example fragments, the document is not > driven by the perspective of an issue tracker at all. I didn't realize that till now. Thanks. It gets abstract quite quickly. That was certainly not the intention. > I think doing so would be very enlightening to the reader. Talk about > how a client can find out the API documentation for an issue tracker. > Talk about how an issue has several operations. Talk about how an > issue can be queried using an IriTemplate. Instead of talking about > collections, you talk about how your issue tracker has a collection of > issues, and how we might interact with it, and so on. Yeah, good point. We need to build a story around this. > You can start with a rough description in prose documentation of what > URLs the issue tracker has and what kind of content is on it, and then > show how we can turn this prose documentation into solid API > documentation and how we can also use some hydra vocabulary to > describe common types of content, such as collections. +1 > =Section 4.1= > > You talk about describing hyperlinks, and then you go into operations. > I'd suggest separating that into two sections. You introduce more than > enough new concepts in 4.1 just concerning describing links already. Yes, we have an open issue (ISSUE-44 [1]) with the probably cryptic name "Restructure spec to talk about application state, resource state, and API as whole" that goes into the same direction. > Concerning those concepts, Example 3 is what? Example 4 is the > representation of a resource, but example 3 is part of the API > documentation, presumably. If it can be part of the representation of > a resource directly, please explain how, as I don't see it. You are right. Example 3 is part of the API documentation (or vocabulary definition). This needs to be made clearer. > Example 3 and Example 3 relate to each other, I think, by way of the @id > "http:/api.example.com/vocab#comments". Example 3 says something about > that IRI, and example 4 then uses that IRI. This relationship needs to > be made extremely and abundantly clear. (if I even got this right) You got it right. > =Section 4.1: operations= > > This should be in a separate section. You introduce a way to describe > operations. These operations, in example 6, are apparently part of the > representation of an issue, *not* part > of the API documentation. Or not; I'm not sure -- @id "/an-issue" Yes, this is an inline operation... it's still in section 4.1 Adding Affordances to Representations. The spec starts talking about ApiDocumentation in section 4.2 Documenting a Web API. > indicates to me this is a particular issue, but the description seems > to be describing the API. Which is it? This is extremely confusing! OK, gotcha. This is about a particular issue, i.e., a specific resource. A Hydra ApiDocumentation is about all resources that make up the API. I see how this might be confusing though. > When you talk about possible operations, don't only describe the > simplest possible form of interaction early on (the > DeleteResourceOperation), but also describe what a > CreateResourceOperaration looks like. I know you do that in 4.2 > example 10, but 4.2 is not about operations. Just describing these > operations really could use a few more words in the spec. OK > The @context in example 6 bothers me a bit; I'd expect a context there > primarily pertaining to the representation of the issue, as opposed to > just the Hydra context. What would that look like? Well, in this simple example all properties come from the Hydra vocabulary (including title and description). This is however an inappropriate shortcut here. Using schema.org might be better. It would look *somewhat* like this: { "@context": [ "http://schema.org/" "http://www.w3.org/ns/hydra/context.jsonld" ], ... } > ==Section 4.2: documenting a web API== > > I think here we might be going from a mostly part-of-resource inline > description as in 4.1 to a out of band API description. Is that correct? Yes > I think you can do such a smooth switch because you describe IRIs with > JSON-LD and it doesn't matter where those IRIs are, in the resource > representation or the API documentation. Is that at all correct? Correct > Is example 8 supposed to be embedded in the supportClass structure > shown in example 7? Yeah > Example 7 has a section 'statusCodes' as a sibling to > 'supportedClass'. But example 10 has statusCodes more sensibly as part > of an operation. I don't understand what the meaning is of statusCodes > in example 7. Ah, section 5.3 finally makes this clear. If you're > going to show statusCodes in the ApiDocumentation *and* Operation > classes both in section 4.2, then this should be described here, not > in 5.3 Or at least include a forward pointer to section 5.3... > Why is it singular supportedClass, and plural statusCodes? You seem to > use singular in other cases, like for supportedProperty, what makes > statusCodes special that it should be plural? This is a left over which we haven't resolved yet. Initially, Hydra used plural and singular terms. We switched all of them to singular a while ago. We already had statusCodes and statusCode so we couldn't simply singularize statusCodes (see ISSUE-34 [2] and ISSUE-27 [3]). > This section talks about classes that are expected or returned by an > operation, but you didn't really demonstrate this in the operation > section before because you used the boring DeletResourceOperation. Mhm... Probably better to describe each concept by itself first and then show how/where it can be used. > Meanwhile, I'm also wondering what the relation is between Hydra class > and JSON-LD @type. You can use a class as a @type, which I see in the > Collections type, but that's not made clear here. And you can presumably > use the class in expects and returns in an operation. Or is that really > the @type? I think a class can be used to describe a type, correct? @type specifies the class of an instance. So { "@id": "/something", "@type": "Class" } Says that the resource /something is an instance of the class Class, i.e., /something is a class itself. { "@id": "/something", "@type": "MyClass" } Is basically the same. Here /something is an instance of MyClass. > So in order to indicate what operations a resource supports I can > embed the supportedOperation and even supportedProperty directly in > that resource, but it's more succint and maintainable to associate > this information with classes. Is that correct? No, "supportedOperation" has to be associated to a class. You need to use "operation" if you want to associate an operation to an instance (resource). supportedProperty doesn't make that much sense for instances AFAICS > Classes in addition allow you to go "closed world" for a type and say > things about the properties a class supports. Is this discussion about > closed world really necessary at this point? Can't you just say the > class allows you to express a few extra things about known properties > for that class? Probably we could leave this out (even though it might be helpful for people with SemWeb background). > Concerning example 8, I'd like to see an example concerning the issue > tracker, just like the other examples. This would help me in > particular when I see "property": "#property". What does this express > exactly? Why is the word "property" used and not something like "key" > or "name"? "property" seems strange to me - we're already in a > SupportedProperty type and now it has a key called "property"? +1 > In general, when you have lists of things (supportedOperation, > supportedProperty, etc) have at least one example contain *two* > examples in that list, instead of only just one ever. This is easy if > you make the examples about the issue tracker. Good point > Concerning example 10, I'm confused by the notion that operations can > also associate with a link: > > * what if the supported operations for the link are inconsistent with > the operations for the class of what the link refers to? What do you mean by "inconsistent" in this context? They don't have to be the same if that's what you are saying. The resource that is the target of the link will be known to support both the operations associated to the link property and the operations associated to its class(es). > * The notion to show only an operation if a user has a permission > implies there is not one API documentation but many, dynamically > generated based on current user permissions. That seems to totally > destroy caching, what am I missing? Shared caches perhaps, not private caches (as the one in your browser e.g.) though. > Alternatively all these operations > need to be embedded within the actual resource somehow and generated > dymamically, but I'm not even sure what that looks like in case of a > link (example please in that case!). And example 10 says *documenting*. In case you embed them, it always looks the same: "linkProperty": { "@id": "/target", "operation": [ ... ] } You don't associate them to the linkProperty but to the resource. > For a GET operation I'd typically signal that in the resource > representation. If the user does not have a permission to GET a > resource, there's no property with a link in the resource, or there is > a property and it's null. Of course that assumes that there is no case > where a user may POST to a resource without being able to GET it... Right > Is this intended to work by having the documentation spell out > multiple types of links, i.e. a > "http://api.example.com/doc/#readonly-comments" and > "http://api.example.com/doc/#readwrite-comments" and then have the > content contain a reference to the link type somehow? If so, an > extensive example is needed that spells this out, as I don't even know > how the content could determine the link type. That's one option. The simpler one in many cases is to introduce a new class (CommentCollection, WritableCommentCollection) and add/remove it as necessary in the resource representations. > Alternatively you could have some kind of special link node that > contains not only the IRI of what is being linked to, but also an > "allowedMethods" list which contains those methods that are allowed, > i.e. "allowedMethods": ['GET', "POST']. Is that possible? This is basically the same as I described above. > = 4.3. Discovering a Hydra-powered Web API= > > Now we finally discuss how a Hydra-powered web API is to be > discovered. This could help enlighten the reader to how things relate > to each other, but if so it should go earlier, and talk about how this > works for the issue tracker. The thing is that this is not strictly necessary if all the operations are declared inline (embedded into resource representations). In that case, you won't need a Hydra ApiDocumentation unless you want it to point to the EntryPoint. > I see a way to use a link header to refer to the API documentation > from the home page. This implies my client is going to the HTML home > page first to pull out that link, and not directly to the API. What if > I go directly to the API, which seems to be the more common thing to > do? I.e. I already *know* the entry point? Right. In that case you already know the entry point but you wouldn't know where to find the rest of the ApiDocumentation. > Consider the case where there *two* different APIs on a site? The link > tag can return two references, and then I could look at the API > documentations somehow to determine the one I want to consume, and > then go to the entry point there. But it seems more reasonable to me > that I go to the right entry point of the API first, instead. Yeah, and that's totally fine. > In discussions it was shown that the entry point (and all sub-points) > can also contain a link header to their documentation. This should > also be mentioned in this document. Good point. That was probably the source of quite a few misunderstandings. > But I'd still like to see this the other way around: you communicate > the entry point to the API to the client, and this contains a link > reference within the JSON (something like example 2) to the API > documentation. This seems to be the way links work within HTML Why is that preferable over an HTTP Link header? > documents: a CSS document doesn't say what HTML document it's about, > but the other way around. Why should it be the other way around for > JSON and Hydra? Because we also want to support the use case which requires to find the entry point. Basically every (human-readable) API documentation contains this. Hydra is no different in this regard. > Having the entry point not part of the documentation also allows this > documentation to be used in multiple places -- if you have the entry > point baked into the documentation it only describes one host ever, > right (or at least prescribes the structure of the absolute path on > that host). Well, in that case you either don't specify an entry point at all or enumerate all of them (if you know them). Nothing will break by doing so but obviously you won't find the entry point if it isn't specified. > =5 Advanced Concepts= > > I think the whole title of "advanced concepts" is a bit of a misnomer; > it's just a grab-bag list of things that aren't particularly more > advanced than anything else. In particular collections would be > happening all over the place. In fact, all of this stuff would be in a > typical API, even a read-only API. Instead if we had a worked out > example concerning an issue tracker we could build up to those > concepts step by step. Do you feel the same about IriTemplates for example? > =5.1 Collections= > > Here we seem to go back to talking about how Hydra can be used as a > vocabulary in resource representation itself, as opposed to being API > documentation. Is that correct? This needs to be made *very* clear -- Yes. Hydra is a vocabulary. It establishes a shared understanding of a couple of concepts. As such it can be used in many different ways. > if you think about Hydra as API documentation you stumble when you > suddenly see an example of a collection with concrete members with > concrete links, and vice versa. It's "A Vocabulary for Hypermedia-Driven Web APIs", not an API documentation format. Any suggestion of how we can make this clearer? > =5.2 Templated links= > > Are templated links supposed to be embedded in the resources or in the In most cases, they will be embedded in resource representations. > API documentation? I think here we move back into the real of API > documentation again as an option. We already discussed my confusion on > how these are referenced. My understanding is that you can include > this directly within the resource description, or refer to it using a > IRI. Both ways of using these aren't immediately obvious, so it'd be > nice to see a more worked out example in the documentation. Really > seeing all the moving parts together, with an idea on what URL they > are, really is useful. I realize JSON-LD allows a variety of > organization of nodes, but a few basic examples would still help the > reader a lot. Instead example 15 leaves the reader to wonder where > this whole IRI template is supposed to be. +1 > Example 16 is not really an example. It's a definition. Instead I'd > like to see a real example where the search property is used. OK > =5.3 Description of HTTP Status Codes and Errors= > > Typo: "The address this issue," -. "To address this issue," Thanks, fixed: https://github.com/HydraCG/Specifications/commit/8255c8b062ff0b6c2c6eca89521 80cec2aa51c78 > See section 4.2 for a discussion of how I think some of this should be > moved to earlier in the text. > > =The API Demo= > > I tried to figure out how an issue tracker is described by going to > the Hydra API demo using the Hydra console: > > http://www.markus-lanthaler.com/hydra/api-demo/ > > But unfortunately using the browser console was rather more confusing > than it should be. Firstly, can the demo server send back > pretty-printed JSON? It's a demo server, after all. OK, I changed this back in July [4] but apparently my server was still running an old version of PHP. It serves pretty-printed JSON now. > The stuff on /api-demo includes all sorts of __activectx and __value > information; it'd be better if that kind of normalization was done on > the client-side so that the reader is not exposed to it. Yeah, but my JSON-LD processor is implemented in PHP :-) > Understanding the large graph at http://www.markus- > lanthaler.com/hydra/console/proxy.php?url=http%3A%2F%2Fwww.markus- > lanthaler.com%2Fhydra%2Fapi-demo%2Fvocab&vocab=1 (confusing URL!) is > also not easy. It's so confusing because it uses a proxy.. the "real" URL is (I know, I should change vocab to apidoc or something) http://www.markus-lanthaler.com/hydra/api-demo/vocab It might be easier for you if you look at the event API demo: http://www.markus-lanthaler.com/hydra/event-api/vocab Thanks a lot for this extensive and very constructive feedback, Markus [1] https://github.com/HydraCG/Specifications/issues/44 [2] https://github.com/HydraCG/Specifications/issues/34 [3] https://github.com/HydraCG/Specifications/issues/27 [4] https://github.com/lanthaler/HydraBundle/commit/38c2edf661a8db59a3753da26d1b 422cedebe833 -- Markus Lanthaler @markuslanthaler
Received on Thursday, 4 September 2014 14:00:47 UTC