- From: Tomasz Pluskiewicz <tomasz@t-code.pl>
- Date: Tue, 8 Jul 2014 13:35:27 +0200
- To: "McBennett, Pat" <McBennettP@dnb.com>
- Cc: Markus Lanthaler <markus.lanthaler@gmx.net>, "public-hydra@w3.org" <public-hydra@w3.org>
On Tue, Jul 8, 2014 at 1:16 PM, McBennett, Pat <McBennettP@dnb.com> wrote: >> -----Original Message----- >> From: Markus Lanthaler [mailto:markus.lanthaler@gmx.net] >> Sent: Monday, July 07, 2014 6:51 PM >> To: public-hydra@w3.org >> Subject: RE: Specifying operations for instances >> >> On 7 Jul 2014 at 19:15, McBennett, Pat wrote: >> > Markus Lanthaler wrote on July 07, 2014 5:03 PM: >> >> On 3 Jul 2014 at 23:40, McBennett, Pat wrote: >> >>> ...in which case Tomasz's UI would probably render a DELETE button >> >>> for '/posts/a' (since the DELETE operation *is* present in the API >> >>> documentation), *but* that button would be grayed out and disabled >> >>> (since the DELETE operation *is not* present in the instance's >> >> representation). That's what I was agreeing with, and I thought you >> >> were saying 'Yes' to too. >> >> >> >> Nope. There's no reason to gray it out and disable that button. If >> >> that would be the case, then associating operations to classes in an >> >> ApiDocumentation would be completely useless as you would have to >> >> repeat exactly the same representation in each "instance representation". >> >> >> > >> > Ok, but what exactly is the "instance representation" telling me then? >> > I can only assume that it's telling me about 'extra' or 'new' >> > operations that it supports, but that were never mentioned in the API >> documentation - is that correct...? >> >> Yeah, that's true and is a direct consequence of the underlying open world >> assumption: >> >> http://en.wikipedia.org/wiki/Open_world_assumption >> >> >> >>> But in b), you then stated that the '...the operations associated to >> >>> the resource itself and the ones associated to its class are merged. >> >>> After that, they are indistinguishable', which seemed to imply that >> >>> we must always 'merge' the operations from the API documentation and >> >>> the resource instance, which from my c) above would mean: >> >>> >> >>> /posts/a operation z, x, y, DELETE (i.e. I must 'merge' all >> >>> operations from the API doc and the resource instance.) >> >> >> >> That's right and the whole idea behind it. >> >> >> > >> > Ok, so again, then I assume there is never a need for an "instance >> representation" >> > to state explicitly that it supports an operation if that operation >> > has already been stated as being supported in the API documentation >> > for the class of this "instance". >> >> Correct. >> >> >> >>> I'm pretty sure that wasn't your intended meaning. I think you >> >>> probably meant 'additional operations appearing in the resource >> >>> instance at runtime should be included (or considered >> >>> 'enabled') by the client, even if they never appeared in the API >> >>> documentation, whereas operations declared in the API documentation, >> >>> but missing from the resource instance can be considered >> >>> 'Unavailable (or 'disabled') at this time''. But anyway that's where >> >>> I was seeing the >> >> inconsistency. >> >> >> >> Nope, that was not was I meant and I hope this email clarifies this. >> >> What value would an operation declared in the API documentation have >> >> if it would have to be declared again in "resource instances" to be >> >> considered "available"? >> > >> > Well, my original thinking was that the API documentation was used to >> > give hints about the current set of 'possibly' supported operations >> > for a 'hydra:class', whereas an instance representation would provide >> > a more concrete set of hints about the operations supported by that >> > instance at that point in time. >> >> No, that's not what was intended. >> >> >> > But I think I understand your point - i.e. the general case would >> > certainly be that most instances would support all the operations >> > stated in the API documentation for their class anyway, so why restate >> > that API documentation for almost every instance. But am I >> >> Right, that was the motivation behind this feature. If that wouldn't be the >> case, I would have left that feature out. >> >> >> > correct then in my assumption above that the only purpose for having >> > resource instances being able to state supported operations is for >> > them to state 'extra' or 'new' operations that they *do* support, but >> > that may not have been stated in the API documentation for their >> > 'hydra:class'? >> >> Yeah, that's correct. Think of comments on a blog. There will be lots of >> them, but there are only very few that you wrote. Thus, it would make sense >> to state that a specific comment can be DELETEd by you in the resource >> representation. >> >> >> > And if that assumption is correct, then is it even possible for a >> > resource instance to give a hint that it explicitly does *not* support >> > a specific operation that *is* stated as supported in the API >> > documentation for that instance's class? (For instance, the API >> >> No, that's currently not possible. The client has to try to invoke the operation >> to find that out. >> >> >> > documentation might state that the 'Products' class may support a >> > 'Special Discount' operation, but a specific instance of 'Product' >> > will only support that 'Special Discount' operation if the user >> > associated with that instance is a 'Privileged User'...?). >> >> This can be addressed by serving different API documentations to different >> users. >> > > Wow - this sentence was a huge light-bulb moment for me :) ! I simply never thought of the API documentation in that way, and checking the Hydra specification again, I can't find any direct explicit references to such an interpretation. > > I think the fundamental reason why this never occurred to me was simply because of my long history of working with API's in the traditional sense. By that I mean working with '#include <...>' header files in C and C++, and then using the keyword 'interface' in Java and C# (and the general guidance to 'always program to interfaces'), and then using IDL in CORBA to define my APIs, and then using WSDL to do likewise for WS-*. In every single example of developing or using an 'API' throughout my entire career I've always been forced to work with a single *static* representation of an 'interface'. > > I think this is the first time I've come across the concept of the API description itself being so dynamic [1], so dynamic in fact that potentially each and every consumer of that API might see a completely different representation of it at runtime! I think that's a big paradigm shift for developers - but I totally agree with the premise. > > So it leads me to think that simply calling this the 'API Documentation' is in fact a very misleading misnomer, given the automatic association any experienced developer (like me) will have between an API and some static description (in fact, in my mind 'API' almost seems to *mandate* a large degree of static-ness!). > My thoughts exactly. I even had an unsent draft with the exact same conclusion and programming API analogy as well. The word document is derived from latin documentum - example, which shares the stem doc- with the word docere - to teach [1]. In that sense I think most people will intuitively understand the ApiDocumentation as a place to learn from. > > Instead I really like the idea of expressly describing Hydra as a vocabulary for describing 'Dynamic Application Programming Interfaces' - i.e. a DAPI, and *not* an API (nor a 'Dynamic API', see [1]). This seems like an opportunity to introduce a new acronym (DAPI) to try to very explicitly and clearly express the fundamental difference between traditional APIs based on the Closed World Assumption, and DAPIs based on the Open World Assumption... > > > [1] I have come across people referring to 'Dynamic APIs' in the sense of totally generic interfaces (what I still call 'void *func(void *);' from my C programming days, or I guess 'Object func(Object o);' nowadays for Java). But those interfaces were always still 'static' in the sense that their descriptions never changed (i.e. they always remain of the form 'void *func(void *)') - but they are considered dynamic in that they simply allow 'anything' to pass into the interface as input, and 'anything' to come out as ouput. > >> >> > I know a resource instance can always reject a request at runtime for >> > 'Special Discounts' if the user is not 'Privileged' (and I know we >> > have the open-world assumption to deal with here!), but I think like >> > Tomasz I was kinda thinking of a UI that could be a bit friendlier >> > than always offering the user every possible operation, but then >> > returning errors to them when they attempt operations that the >> > server-side probably knows already that they can't actually perform >> >> There are multiple ways to achieve that: >> - just use inline operations >> - use inline operations for things that vary by user/instance/etc. >> - serve different API documentations for different users >> - use multiple classes and use them accordingly (Comment, >> RemovableComment) >> > > Yep - plenty of avenues there alright. I get it now! > Indeed it was just as enlightening to me as well! The way Hydra empowers developers to build dynamic or generic systems is great. Though I still cannot fully agree that developers will never want to read the API representation (be it a JSON-LD document or generated HTML documentation). We are humans after all and humans will implement client systems. I think it's great that we are closing in on a solution with the issue Markus has created [1]. Shall we move to a new thread? Markus, would you start one so that we can see whether we are on the same page and go from there? [1] https://github.com/HydraCG/Specifications/issues/59 > >> >> >> -- >> Markus Lanthaler >> @markuslanthaler >> >
Received on Tuesday, 8 July 2014 11:37:02 UTC