Re: Specifying operations for instances

On Sat, Jun 14, 2014 at 9:20 PM, Markus Lanthaler
<markus.lanthaler@gmx.net> wrote:
> Tom, you didn't send the reply to public-hydra but just to me. I forwarded your mail to the list so it gets archived properly (and everyone gets it)
>

Sorry. I reconfigured Gmail to "reply to all" by default.

>
> On 13 Jun 2014 at 10:02, Tomasz Pluskiewicz wrote:
>> On Fri, Jun 13, 2014 at 12:33 AM, Markus Lanthaler wrote:
>>> On 11 Jun 2014 at 20:38, Tomek Pluskiewicz wrote:
>>>> The first is to use the supportedOperations property on the Class
>>>> resource. This gives the client a general view on all possible
>>>
>>> Please note that we operate under the open world assumption [1]. This means, you have to
>> acknowledge that you don't know if these are *all* possible operations or just a few of
>> them. You just know that the ones you see are possible.
>>>
>>
>> Open world assumption doesn't help much here. I see the analogy to
>
> It doesn't help but it is important to understand it. You wrote in your initial mail (emphasis mine):
>
>     "This gives the client a general view on **all** possible
>      interaction with all resources of that type.
>
> I just wanted to make sure we are on the same page.
>

Definitely.

>
>> predicates' domains and ranges. Given a predicate with a domain class
>> specified doesn't however imply that every single instance of that
>> class will actually exist in such relationship.
>
> Right
>
>
> [...]
>> Also IMHO the open-world assumption doesn't work here. It implies that
>> the clients can actually send any request to the server, because there
>> *could be* more operations. However the server doesn't operate under
>> OWA and will reject requests that are not supported.
>
> The server does what it does. You won't know for sure before you try it. It is a distributed system and you don't control the server. Furthermore, an API can point to resources in other APIs.
>
>
>>>> I'd like to know your opinion/guidelines about some details:
>>>>
>>>> 1. Let there be a class, which supports operations X and Y. Let there
>>>> be an instance of that class, whose representation has operation X
>>>> included directly in it's representation, but not operation Y. Should
>>>> the client in such case assume that operation Y is not allowed on the
>>>> that resource?
>>>
>>> No. The client should interpret things exactly the same way regardless
>>> of where/how they are defined. In this case, both X and Y should be
>>>
>>
>> It's like saying the every HTTP resource has the GET, POST, PUT, PATCH
>> etc actions supported and one should assume that they are supported. But
>
> Why is it the same?
>
> You explicitly state that a resource is of a certain type. You also state that all instances of that type support operations X and Y. Finally, you state again that that specific resource supports operation X. Why should that imply that Y isn't supported?
>

It all boils down to defining what supporting an operation means. Let
me reword my HTTP analogy. Having a resource, that we know exists,
implies that it supports the HTTP verbs. But requesting OPTIONS would
hypothetically tell us that only GET is actually allowed. Maybe due to
the current state of the resource or the nature of the requesting
client (ie. authorization etc.). We could try any other method but we
are bound to get a 405 Method Not Allowed response.

With hypermedia we're one level higher but I think the issue is
similar. Let's move to a more real-world example. We know that there
exists a resource, which as instance of class ForumPost. The ForumPost
class supports simple PUT and DELETE. However some buisness rule could
say that user that created the post can delete it. So if any other
user has authenticated, the DELETE operation will not be inculded in
the post's representation.

I understand that the resource still supports the DELETE because it is
an instance of the ForumPost class. But in very practical terms, would
you consider the absence of the DELETE operation in the instance's
representation a good enough clue for the client not to render a
delete button?

>
>> it doesn't mean that every single resource will allow any request.
>> That's where OPTIONS come in the case of raw HTTP. If I were
>> implementing a client, I would expect explicit information what
>> operations I can perform next and not guess based on all possibilities.
>
> See above. You get explicit information. Obviously you need to use it correctly, but that applies to everything - including OPTIONS.
>

That is the kind of guidelines I'm looking for. Suggestions for
implementing a well-behaved clients and servers. As you say, a client
could ignore obvious clues or the server could mislead the client...

>
>> And actually I'm surprised that you would treat supportedOperations
>> and operation properties equally. If so why actually have two
>> properties in the first place?
>
> If there would just be one property, "operation", what would
>
>     http://www.example.com/a/Class operation ....
>
> mean? Would it mean that all instances of that class support that operation? Or would it mean that http://www.example.com/a/Class supports that operation? Having two properties makes this unambiguous.
>

Of course, that makes sense! I meant something else though, that you

Actually, it has just crossed my mind that maybe the 'operation'
predicate isn't named just right. SupportedOperation indeed makes
intuitive sense, that instances of that class can be potentially
interacted using the described operations. How about calling the other
predicate 'allowedOperation' instead. Thus one would imply that
requesting any other supported operation could *potentially* yield a
405 status code? Or would you think it's semantics were too strong?

>
>>>> What do you think about using the
>>>> OPTIONS verb instead and in returning the operations in response. This
>>>
>>> I'm not a big fan of OPTIONS. It has several severe drawbacks... e.g.
>>> it requires you to make two requests for each resource and it isn't
>>> cacheable.
>>>
>>>> way every resource can have it's own set of available operations based
>>>> on for example it's state or the user's permissions and at the same
>>>> time the server side code keeps a clear separation of concerns. Would
>>>> you think that the benefits outweigh the costs of additional traffic?
>>>
>>> No. The simpler and cleaner approach is to bind operations to classes or properties in the
>> API documentation and then dynamically add/remove those classes/properties from the
>> resources. Think of something like "PublishedBlogPost". It's very cheap to create new types
>> and clients don't need to understand them in order to find the operations. Have you thought
>> about that already?
>>>
>>
>> +1
>> This is actually as neat idea and no, I haven't thought about that.
>>
>>
>> I think I see your point better now. You suggest that the application
>> could keep the ApiDocumentation and then choose whatever relevant
>> operations should be added to a resource instance? I agree that it's
>
> You have the choice. You can describe all operations in the API documentation if you want and then add/remove them from resources by
>   - asserting that the resource is/is not an instance of a specific classes
>   - add/remove properties from the representation
>   - reference those operations directly from the representation
>

Do you mean API documentation or resource representation?

>
>> up to the client to interpret it as it sees fit. However I still think
>> that Hydra itself should be a more precise tool with if not rules, at
>> least some guidelines on the semantics behind operations.
>
> This doesn't make Hydra less precise. It just means that there are multiple ways to achieve the same thing. Generally, we should try to avoid that but in this specific instance I think it's a quite valuable feature.
>

I'm sorry. now I don't understand. Which is the valuable feature?

>
> I don't really understand what you mean by "if not rules". What " guidelines on the semantics behind operations" are missing in your opinion?
>

Poor wording in my last sentence. I meant the guidelines would be more
appropriate than rules.

I think what's missing is or vague is:
1. what clients should assume if a resource representation has some
but not all of the supported operations defined by it's class
2. what clients should assume if a resource representation doesn't
include any operations explicitly


And actually I looked at example 10, where it says "This is often
helpful when certain operations depend on the permissions of the
current user. It makes it, e.g., possible to show a "delete" link only
if the current user has the permission to delete the resource.
Otherwise, the link would simply be hidden in the representation.".
Does it mean the API documentation representation?

>
> --
> Markus Lanthaler
> @markuslanthaler
>
>
>

Received on Saturday, 14 June 2014 21:29:13 UTC