Re: Modeling permissions with Hydra

Hi,

Sorry for coming back to this old thread again, but I just haven't had
time to reply to this before now.

2015-11-26 11:40 GMT+01:00 Markus Lanthaler <markus.lanthaler@gmx.net>:

> I would say that an operation isn't available for all resources of that type, the
> ApiDocumentation shouldn't say so. It's trivial to introduce an additional
> (sub)class (BlogPost vs. EditableBlogPost) and attach to operation to that
> class instead.. or attach the operation to the resource directly.

But the state of the resources and the availability of their
operations is transient. There's n indefinite set of variables that
affect which operations are available on a resource in its current
state. Obvious ones are authorization and lifecycle, but then you can
have a load of external and invisible factors, such as the state of
modules the resource depends on.

>> 1. Force the client to reload the ApiDocumentation
>> 2. Make the client try to perform the operation and respond with 403 or 405
>>
>> ...are not optimal. How would you do the first one server-side?
>
> Point to a different ApiDocumentation? Similar to how you point to a different,
> longly-cached CSS/JS file when deploying a new version of a website.

That could work. And while I agree that we need much more intelligent
clients than what's currently "out there", I think this is might be
stretching it. I think the CSS analogy discussed further down is proof
of that.

>> And the second requires at least one extra request, which is something we
>> can avoid if possible, as hypermedia driven API's are chatty enough by
>> the nature of HATEOAS.
>
> Right. It is not always avoidable though. There might pass significant time
> between the client receiving the resource and executing an operation
> based on it.

True. That would often incur a lot of other problems too, though (such
as concurrency issues), so I think that's expected. That also makes it
a use case I don't think we should optimize for.

>> I didn't write this, but I agree with the sentiment. A way to do this is
>> to say that the operations in ApiDocumentation are just a (complete)
>> list of what the client needs to support, but that the inline operations
>> are the ones supported in the resource's current state. This incurs
>> duplication, but also gives the server more control.
>
> The ApiDocumentation would be of very little value then.

Not at all. It would be a "specification" an implementor can follow to
implement the different operations and then use inline metadata to
figure out which of the implemented operations to use in the
resource's current state.

> Assumptions like having a complete overview etc. are very dangerous
> in the context of large, distributed systems.

I don't think it's dangerous if the details of the overview is
considered volatile, so it is expected that their existence will vary
on each request.

> A resource can have multiple classes, so you can combine them.

Yes, but that does only give you the power of adding properties and
behaviors to a resource; it doesn't allow you to remove anything.

> Also, there always the option to simply list the operations inline if
> listing them upfront becomes impractical.

I believe doing both is very valuable. Only discovering operations,
properties, etc. inline will lead to surprises and breaks. Only
implementing based on a naïve understanding that the ApiDocumentation
is written in stone and that the resources described in it won't
change will also lead to surprises and breaks. Combining the two in an
elegant and intuitive way will lead to easy implementation based on
the ApiDocumentation and flexible clients based on inline metadata.

>> ... dynamically changing the client will potentially break consumers
>> of the client, especially if the client is statically typed.
>
> If that breaks consumers of the client, they won't be able to deal with
> inline operations either, right?

True; however you convey the metadata to the client, the client won't
work well in a statically typed language if the client itself is 100%
fluid and dynamic.

>> Yes, but to continue that analogy, it's not very common that the
>> centrally referenced CSS changes dynamically based on the state of the
>> resource.
>
> Right, that's the reason why I'm not a big fan of doing that (but mention
> that is possible). I find using different classes (like in CSS) much better.

Yes, but with CSS, it's possible for one class to replace and remove
every property defined by another. That is not possible with either
Hydra (in its current form), nor RDF, as far as I'm aware of.

> Right. You can always change the URL to the ApiDocumentation to
> force a refresh for (different version for logged-in vs. logged-out users
> for instance).

Yes. That's quite common for CSS and JS. But none of those languages
describe how you should interpret and operate on the resource you're
currently looking at. You could say JavaScript does this in a way, but
it's not declarative, so it's not really an apple-to-apple comparison,
imho.

>> I feel like the mental model of having a centrally referenced
>> ApiDocumentation that is supposed to change dynamically given the
>> current resource's state is hard to understand.
>
> +1

I'm glad you agree. :-)

>> This usage of dynamically applying classes to instances in runtime
>> might work. I'm not sure how to model it, but if you could make the
>> operations general across several different resources, the operations
>> themselves could be attached to the "role" as an aspect[1].
>
> How many operations do you typically have to deal with for a resource
> (type)? In the order of 1-10? 10-20? 20-50? 50-100? More than 100?

That's very hard to say. In our applications, we use PATCH something
like 90% of the time (if you exclude GET). The problem with this is
that since the payload is dynamic (JSON Patch), it's pretty much
impossible to pre-enumerate all possible variations of the payload.
For POST, PUT and DELETE, it's much easier.

>> Yes, but the current model is optimized for extending
>> hydra:supportedOperation in hydra:operation, not overriding or
>> limiting hydra:supportedOperation. I think we need a way to say in a
>> declarative way that a supported operation is not available at the
>> current state of the resource.
>
> I need to think a bit more about this.

I hope you've had time to think a bit more about this now. :-)

-- 
Asbjørn Ulsberg           -=|=-        asbjorn@ulsberg.no
«He's a loathsome offensive brute, yet I can't look away»

Received on Thursday, 21 January 2016 08:44:05 UTC