Re: some more feedback

Hi there,

On Wed, Sep 17, 2014 at 6:28 PM, Markus Lanthaler
<markus.lanthaler@gmx.net> wrote:
> On 16 Sep 2014 at 22:03, Martijn Faassen wrote:
[snip]
> Unfortunately, I don't understand what you mean by
>
>> I'd rather read "You can use a class to
>> express a few more things about a @type" or something like that.

As far as I understand, the Hydra spec doesn't actually make explicit
that I can use 'class' to define something I can use in @type. I have
to infer this from the context of how they're used in various
examples. I'd just prefer it if it actually said so out loud.

>> again. (what happens if two classes describe contradictory
>> information, i.e. one says a property is required and the other one
>> says it isn't..
>
> They are different classes, how could it be contradictory?

Well, what if I use both classes in a @type array and they describe
the same property, and one says it is required and the other one says
it isn't? What happens? I guess it resolves to required, but the spec
might want to actually say so.

>> Probably union again? What about writeonly and
>> readonly? I should check the spec for that too)
>
> That's indeed a problem. We thus decided in ISSUE-14 [2] to rename readonly/writeonly to readable/writeable

Ah, that sounds better indeed.

In general some language about taking the union of things helps. I
imagine if you're a RDF person you probably already do this
automatically, but I am still assuming this spec is not only for
people immersed in semantic web stuff.

[snip]
>> Don't you think the developer reading the
>> documentation needs to know that if a user gained permissions they'd
>> get more operation?
>
> I don't think I can give you a general answer to this question. It depends. As said before, this is not always the right thing to do and there are alternative to
> achieve the same.

Sure, it depends, but I think I'm describing a common assumption here:
that we typically expect the documentation to be static, and not
depend on permissions. I can see how you might want to generate
different documentation profiles that are permission-based and that in
some documentation profiles the operation is missing, but such a
profile would not be dependent on the permission of the user of the
service under description.

[snip]
>> * even if the token was changed each time authorization changes, there
>> is still no way to signal to the client that the API documentation
>> should be refreshed. *If* the client knew to reload API documentation
>> it'd get a new version, but how is the client supposed to know it can
>> do this? Any operation may potentially change a user's permission, and
>
> By the Vary header. It says: if you cache this, take care that it depends on these headers (Cookie, Authorization, ...), not just the URL. As soon as they
> change, the cache is automatically invalidated.

Okay, this may be more about HTTP but I think it does relate to Hydra.
Maybe you're proposing something like this:

We need to know whether the API documentation has become invalid. We
need to know this so we can fetch it again from the server and then,
say, regenerate a Python or JavaScript API. The Vary header could be
used to invalidate the API documentation. (it'd not cover all cases;
some other client you have no knowledge of may add permissions or take
away permissions from you; this would never cause a change to your
cookie)

If we write a custom client, we may have an API to the HTTP cache so
we can check whether the cache for the API documentation URL was
invalidated.

We need to do this check before each new interaction with the service
described by the documentation, as in the mean time a permission may
have been taken away from us. Or we could only do it whenever we
actually get a HTTP error code from the service as I this is a signal
our API documentation is out of date?

But what if we don't have such an API to the HTTP cache? Let's take a
web browser -- do we have programmatic access to the browser cache? I
don't think so, but I may be missing something.

If not, I don't see how we can avoid doing another request of the
documentation URL. The response may then come from the browser cache
or go to the actual underlying service. We then need to detect whether
the response was unchanged somehow, and we can't use a version number
or timestamp as we're talking about permission-dependent differences.
As far as I understand, we can't rely on the 304 status code as that
only comes from the server -- and a 200 status code may in fact mean
we get it from the cache.

I think one mechanism to do this is to make the server return an ETag
and associate the ETag with our generated API. Then each time we
reload the Hydra docs we check whether the ETag we get from the
response is different, and if so, we regenerate the API.

In order to have up to date API documentation before we do a single
request to the service, we'd need to do a request for the API docs as
well. It might not in fact hit the server due to the cache of course,
but there's still a request/response cycle.

But perhaps my assumption that API documentation on the client need to
always up to date is incorrect, and we only refetch the API
documentation when the server does not accept our request and returns
a HTTP error. The HTTP error is the signal to us that our API
documentation has become out of date and we need to refresh it.

>> I wasn't aware that REST required that the types of resources
>> themselves can change on the fly. I thought it was about the client
>> having knowledge about the types of resources and how to follow links
>> between resources.
>
> I don't know what you mean by "the types of resources". You get a response from the server and should be prepared that it might look different than what you
> expected. Of course it is in the interest of the API provider to minimize surprises and not introduce breaking changes.

Let me try to describe it better.

If you have a RESTful client, it:

* doesn't have hardcoded knowledge about what URLs exist on the server
except a single entry point. Related to this, doesn't have hardcoded
knowledge about what types are expected from particular URLs.

* it follows links between resources to get to new resources.

* But it may still have hardcoded knowledge about the *types*. For
instance, a web browser has hardcoded knowledge about what to do with
the HTML type and the CSS type and the image type and the JavaScript
type.

You seemed to be saying that to be truly RESTful, the client also
needs to dynamically adjust its *interpretation* of the types (even
during a short-term interaction with the server), but I didn't think
that was a requirement. It may be a nice addition but you can still do
hypermedia without it.

This ties into approaches to versioning.

If you have a versioned service, and you have a separate entry point
for each version and separate API documentations for each version,
then the client can make the assumption that the types offered by the
API do not change in a backwards incompatible way as long as the
service exists. In order to ensure you get information about new
operations or properties offered by existing types you might still
want to refresh the API documentation once every while, but this is
going to be an explicit operation, and not refreshing the API
documentation will not break your client.

What we've been talking about above is an approach where the API
documentation about types can change at any moment, including in
backwards incompatible ways (taking away an operation due to some
permission change, for instance), and the client needs to be prepared
to change its interpretation of types at any time during an
interaction. This is a very different approach, and rather unfamiliar
territory in the current hypermedia API landscape, I think. It's also
RESTful, but it's not the only approach to REST that exists.

It's interesting to compare this approach to the way a single page web
application functions. In a single page web application, the behavior
of the application is determined by associated JavaScript code.
Interactions with the server using AJAX won't cause that JavaScript
code to be invalidated and reparsed. Instead an explicit full page
reload is required to do this. You could create an explicit mechanism
where the server can request a full page reload to happen, but it's
important to note that this mechanism is indeed explicit. It's not
that the single page application itself verifies before each
interaction with the server whether it should reload itself (and thus
its JavaScript resource).

I think in a typical use of Hydra, we're going to be dealing with
services that offer backwards compatibility guarantees and potential
explicit points of reloading of API documentation from the server,
more like the single page web app model.

Regards,

Martijn

Received on Wednesday, 24 September 2014 10:07:05 UTC