RE: Specifying operations for instances

On 14 Jun 2014 at 23:27, Tomasz Pluskiewicz wrote:
> On Sat, Jun 14, 2014 at 9:20 PM, Markus Lanthaler wrote:
>> On 13 Jun 2014 at 10:02, Tomasz Pluskiewicz wrote:
>>> 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.

That's a fallacy. You are not bound to get a 405. The likelihood of getting it will be much higher, I agree. But the result OPTIONS returns is just a hint. The moment you receive, it might already be outdated. You have to accept that you are working with a massively distributed system. Things don't work they they do on a single machine.

You should look at "supported operations" the same way. It is a hint the server provides the client. It neither has to be an exhaustive list of *all* operations that are supported by the server nor does it mean that if a client invokes such an operation that it succeeds (or that the server still supports it for that matter). I know this is not what most people want to hear but there's no way round it in a distributed system without central coordination.


> 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.

Right.


> 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?

Yes, with the caveat that the ApiDocumentation doesn't tell me otherwise.


>>> 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?

Yes. It would also foster the wrong impression that allowedOperations cannot yield a 405 status code.


>>> 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?

I meant adding/removing them from the resource representations but actually you can do it as well in the API documentation as well. It’s a resource as every other in that regard.


>>> 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?

That you can associate an operation to a) a resource directly, b) a property, and c) a class.


>> 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

The operations associated to the resource itself and the ones associated to its class are merged. After that, they are indistinguishable. Again, it doesn't matter where the operations are asserted.


> 2. what clients should assume if a resource representation doesn't
> include any operations explicitly

Same as above.


> 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?

Representation:

  {
    "@id": "/posts/1",
    "@type": "ForumPost",
    "title": "My awesome post",
    ...
    "delete": "/posts/1"
  }

Depending on the user's permissions, you either include or exclude that "delete" property from the representation.



--
Markus Lanthaler
@markuslanthaler

Received on Sunday, 15 June 2014 19:09:50 UTC