Subject: Re: [apps-discuss] FYI: LINK and UNLINK

From: Julian Reschke <[email-masked]>
Date: Wed, 06 Nov 2013 02:02:38 +0100

On 2013-10-29 06:59, James M Snell wrote:
>
> On Oct 28, 2013 10:48 PM, "Mark Nottingham" <[email-masked]
> <mailto:[email-masked]>> wrote:
>  >
>  >
>  > On 24/09/2013, at 5:17 AM, James M Snell <[email-masked]
> <mailto:[email-masked]>> wrote:
>  >
>  > > Just a general FYI... I have submitted iteration -04 of the
>  > > LINK/UNLINK draft with a few minor editorial fixes... and, I have
>  > > formally requested Last Call status as an Independent Submission on
>  > > the Standards Track.
>  > >
>  > > http://tools.ietf.org/html/draft-snell-link-method-04
>  >
>  > In Section 2 of -05:
>  >
>  > "For any pair of resources, exactly one relationship of any given
> type can exist."
>  >
>  > That's a new and apparently backwards-incompatible change to the
> model of linking on the Web... e.g., consider "stylesheet".
>  >
>
> No, read it again, as a uniqueness constraint on the tuple (resource,
> link relation, resource). That's not new or novel.
> ...

Not convinced.

Consider the various target attributes, or extension parameters. If they 
do not contribute to the uniqueness constraint, you *are* constraining 
the linking model.

Best regards, Julian

---

From: James M Snell <[email-masked]>
Date: Tue, 5 Nov 2013 17:06:43 -0800

Give me a viable, non theoretical use case where the other target
attributes and extension parameters would make a difference and I'll
reconsider that constraint.
On Nov 5, 2013 5:02 PM, "Julian Reschke" <[email-masked]> wrote:

> do not contribute to the uniqueness constraint, you *are* constraining the
> linking model.
>
> Best regards, Julian
>

---

From: Julian Reschke <[email-masked]>
Date: Wed, 06 Nov 2013 02:09:12 +0100

>    http://tools.ietf.org/html/draft-snell-link-method-04

Hi James,

some feedback:

- you may want to talk about what kind of processing of the link target 
happens, such as: is the server allowed or even required to check the 
target's existence (thus can LINK create "dangling" links?) If it does, 
an example would help (status code etc)

- clarify whether an anchor parameter should either be ignored or be an 
error

- you and I know that success could be 200 or 204, but if you don't have 
it at least in the examples, at least some people will be confused (and 
argue whether it should be 201 :-)

- is it an error to try to remove a link that doesn't exist? What if I 
try to UNLINK one existing and one non-existing one?

Best regards, Julian

---

From: James M Snell <[email-masked]>
Date: Tue, 5 Nov 2013 17:12:56 -0800

Excellent feedback. Thank you. Will incorporate it.
On Nov 5, 2013 5:09 PM, "Julian Reschke" <[email-masked]> wrote:

> target's existence (thus can LINK create "dangling" links?) If it does, an
> example would help (status code etc)
>
> - is it an error to try to remove a link that doesn't exist? What if I try
> to UNLINK one existing and one non-existing one?
>
> Best regards, Julian
>
>

---

From: Julian Reschke <[email-masked]>
Date: Wed, 06 Nov 2013 02:13:55 +0100

> reconsider that constraint.

I'll try, but in the meantime it would be good if you could explain why 
the constraint is there in the first place :-)

Best regards, Julian

---

From: James M Snell <[email-masked]>
Date: Tue, 5 Nov 2013 17:18:54 -0800

It exists because (a) I couldn't come up with any viable, non theoretical
use cases where other attributes would really matter and (b) the current
model works in practice for everything I've done with it.

---

From: Mark Nottingham <[email-masked]>
Date: Tue, 5 Nov 2013 17:22:25 -0800

My understanding (perhaps misplaced) was that it was there so you could replace existing links in a deterministic way.

The only other way that comes to mind is to mint a new ‘id’ (or similar) attribute that identifies the instance of the link; e.g.,

Link: </foo>; rel=“bar”; title=“whatever”; id=abc
Link: </foo>; rel=“bar”; title=“the other link to whatever”; id=def

I will point out that in some use cases, it’s not unknown to have multiple links of the same type and same target URI in the same document, but with different target attributes. In these cases, Julian’s concern is valid.

Regards,

On 5 Nov 2013, at 5:18 pm, James M Snell <[email-masked]> wrote:

> It exists because (a) I couldn't come up with any viable, non theoretical use cases where other attributes would really matter and (b) the current model works in practice for everything I've done with it.
> 
> I'll try, but in the meantime it would be good if you could explain why the constraint is there in the first place :-)
> 
> Best regards, Julian

--
Mark Nottingham   http://www.mnot.net/

---

From: Julian Reschke <[email-masked]>
Date: Wed, 06 Nov 2013 02:22:50 +0100

On 2013-11-06 02:18, James M Snell wrote:
> It exists because (a) I couldn't come up with any viable, non
> theoretical use cases where other attributes would really matter and (b)
> the current model works in practice for everything I've done with it.

James, that's an explanation why you think it's ok to add that 
constraint, but it doesn't explain why it's *needed*.

If you took it out, would that cause any problems somewhere else?

Best regards, Julian

---

From: Julian Reschke <[email-masked]>
Date: Wed, 06 Nov 2013 02:32:54 +0100

> My understanding (perhaps misplaced) was that it was there so you could replace existing links in a deterministic way.

You can only replace a link by UNLINKing it first, right?

> Link: </foo>; rel=“bar”; title=“the other link to whatever”; id=def

Or by giving it its own URI... :-)

Best regards, Julian

---

From: James M Snell <[email-masked]>
Date: Tue, 5 Nov 2013 18:52:59 -0800

Sorry, my answer was a bit abbreviated as I was heading out to help
coach the kids soccer practice... Mark's answer touched on the more
complete answer.

The way this is defined, LINK (and UNLINK) are idempotent requests. If
I send the following request twice, the link
(/my/resource,"foo",/other/resource) still only exists once.

  LINK /my/resource HTTP/1.1
  Host: example.org
  Link: </other/resource>; rel="foo"

I could send a separate LINK request connecting the same two resources
using a different link relation.. creating a separate link...

  LINK /my/resource HTTP/1.1
  Host: example.org
  Link: </other/resource>; rel="bar"

No matter how many times I send that request, there is only one link
established.

Whether or not additional target attributes and extension parameters
are considered is entirely up to how the server chooses to utilize the
link relationship. If, after I send the second request above, I send
another:

  LINK /my/resource HTTP/1.1
  Host: example.org
  Link: </other/resource>; rel="bar"; title="this is the bar link"

I would expect that -- if the server treats the target attributes as
something worth paying attention to -- the existing bar link (if one
exists) would be modified using the new attributes.

Per your specific question, yes, we could take all of the target
attributes and extension parameters into consideration when
determining uniqueness of the link, but doing so would introduce
significantly more complexity, especially when one comes back later
and attempts to do an UNLINK -- the client would be required to
duplicate *all* of the target attributes/extension parameters used to
establish the original link.  For instance, suppose I did:

  LINK /my/resource HTTP/1.1
  Host: example.org
  Link: </other/resource/1>; rel="foo"; hreflang="en"; ext=foo
  Link: </other/resource/1>; rel="foo"; hreflang="fr"; ext=bar

And suppose that later on I want to UNLINK the second of the two, I
would have to send:

  UNLINK /my/resource HTTP/1.1
  Host: example.org
  Link: </other/resource/1>; rel="foo"; hreflang="fr"; ext=bar

Which implies that my UNLINK'ing client has full knowledge of the
complete set of attributes used to establish the link in the first
place ... which it may not (remember, we currently have no
standardized way of enumerating all of the links that have been
established).

So, by defining the uniqueness constraint as (context,link
rel,target), we greatly simplify the model... and yes, that
simplification comes at the cost of some functionality -- but given
that I have not yet seen a viable, non-theoretical use case, I view
that loss as acceptable. I'm definitely open to be convinced otherwise
(for instance, I could quite easily be convinced that the hreflang and
type attributes ought to be considered part of the uniqueness
constraint)

Is that a better answer?

- James

On Tue, Nov 5, 2013 at 5:22 PM, Julian Reschke <[email-masked]> wrote:
> James, that's an explanation why you think it's ok to add that constraint,
> but it doesn't explain why it's *needed*.
>

---

From: James M Snell <[email-masked]>
Date: Tue, 5 Nov 2013 19:03:17 -0800

Some specific answers,

On Tue, Nov 5, 2013 at 5:09 PM, Julian Reschke <[email-masked]> wrote:
[snip]
> example would help (status code etc)

No specific processing steps are required by the server. It MAY check
to see if the target exists but is not required to do so (and, in some
cases, such checks could be impractical or impossible).

> - clarify whether an anchor parameter should either be ignored or be an

You mean fragment identifier, correct? If so, the answer is: No,
fragment identifiers MUST NOT be ignored. The target URL ought to be
considered exactly as given (with proper consideration given to
relative URL's, of course). For instance, the following would create
two separate links:

  LINK /my/resource HTTP/1.1
  Host: example.org
  Link: </other/resource#foo>; rel="baz"
  Link: </other/resource#bar>; rel="baz"

> - you and I know that success could be 200 or 204, but if you don't have it
> at least in the examples, at least some people will be confused (and argue
> whether it should be 201 :-)
>

201 implies that a resource is being created... which might not
actually be the case. I could take some time to draw that out in the
draft, if necessary.

> to UNLINK one existing and one non-existing one?

Nope, it's not. The UNLINK request is idempotent and always has the
same result... If I send an UNLINK that identifies one existing link
and one non-existing link, the result in the end is the same...
neither link between the two resources will exist (which is the exact
intent of the request). The server would simply ignore the request to
unlink the non-existent link.

And no, there is no need to UNLINK before replacing/updating an existing LINK.

- James

---

From: Julian Reschke <[email-masked]>
Date: Wed, 06 Nov 2013 16:11:31 +0100

>    Link: </other/resource>; rel="foo"

Yes.

> No matter how many times I send that request, there is only one link

Yes.

> exists) would be modified using the new attributes.

I agree that this makes sense for "title", but I'm not convinced that 
the same is true for every possible parameter.

>    Link: </other/resource/1>; rel="foo"; hreflang="fr"; ext=bar

Yes. It would need to match all parameters. Why is matching all 
parameters more complex than matching one?

> standardized way of enumerating all of the links that have been

Wait. What's the point in LINK if the link that you create does not show 
up in a GET response? Maybe we need to clarify *that* first.

> type attributes ought to be considered part of the uniqueness

What's the material difference from matching all parameters then?

> Is that a better answer?

Yes.

Best regards, Julian

---

From: James M Snell <[email-masked]>
Date: Wed, 6 Nov 2013 07:27:35 -0800

Whether and how a server surfaces links is undefined by this spec. There
are cases where exposing the link would be wholly unnecessary. There are
also cases where the server could significantly alter or augment the
established link with additional detail. My goal with this spec is only to
define the method characteristics.

Regarding the main question about whether or not to include target
attributes in the uniqueness constraint, the question becomes: which target
attributes should be considered?
On Nov 6, 2013 7:11 AM, "Julian Reschke" <[email-masked]> wrote:

> I agree that this makes sense for "title", but I'm not convinced that the
> same is true for every possible parameter.
>
> Yes. It would need to match all parameters. Why is matching all parameters
> more complex than matching one?
>

---

From: Julian Reschke <[email-masked]>
Date: Wed, 06 Nov 2013 16:36:08 +0100

On 2013-11-06 16:27, James M Snell wrote:
> established link with additional detail. My goal with this spec is only
> to define the method characteristics.

I have no problem with that, but in the end something needs to come out 
that is usable.

I agree that the server may want to alter/augment the links. Maybe the 
response body then should reflect what was set?

> attributes in the uniqueness constraint, the question becomes: which
> target attributes should be considered?

All of them?

Best regards, Julian

---

From: James M Snell <[email-masked]>
Date: Wed, 6 Nov 2013 08:18:59 -0800

On Wed, Nov 6, 2013 at 7:36 AM, Julian Reschke <[email-masked]> wrote:
> I have no problem with that, but in the end something needs to come out that
> is usable.
>

Thus far I haven't had any practical need for this... so, again, I
would go back to the question about viable, non-theoretical use cases.

>> target attributes should be considered?

"All of them" becomes impractical for the reasons I've already given,
particularly without clearly defined, viable, non-theoretical use
cases.

That said, here's a compromise: Let's expand the uniqueness constraint
to include anchor, hreflang and type. Doing so ought to cover the vast
overwhelming majority of the possibly viable use cases. I can also say
that the server MUST consider the remaining target attributes to be
significant in that, *if* the server chooses to surface those links in
some representable manner, the most recently received values for those
MUST be included. Is that better?

(btw, getting back to your earlier question about the anchor
attribute, I had honestly completely forgotten about the anchor target
attribute! I've never actually seen it used in any practical sense so
it had completely slipped my mind... to answer that particular
question, yes, the server MUST consider the anchor attribute as being
significant. I'll add a few more examples)

- James

---

From: Julian Reschke <[email-masked]>
Date: Wed, 06 Nov 2013 17:56:35 +0100

> particularly without clearly defined, viable, non-theoretical use

I don't understand how "all of them" can be impractical when "two of 
them" works.

Furthermore, how does the (current) lack of a use case affect the 
practicability?

> MUST be included. Is that better?

I don't think it resolves the issue...

Best regards, Julian

---

From: James M Snell <[email-masked]>
Date: Wed, 6 Nov 2013 09:13:34 -0800

[snip]
> I don't understand how "all of them" can be impractical when "two of them"
> works.
>

Not intending to be rude, but I've already answered this... it has to
do with the amount of a priori knowledge a client needs to unlink or
update a single link relationship.

> I don't think it resolves the issue...

Is it at least a step in the right direction?

- James

---

From: Julian Reschke <[email-masked]>
Date: Wed, 06 Nov 2013 19:05:33 +0100

> update a single link relationship.

I don't see the material difference.

If the client has no reliable way to find out what links are there it'll 
be essentially restricted to edit those that it created itself.

It seems that this is the issue that needs to be addressed.

> Is it at least a step in the right direction?

Well yes, it includes more parameters, but what I'm mainly concerned 
with parameters that we don't know yet.

Best regards, Julian

---

From: James M Snell <[email-masked]>
Date: Wed, 6 Nov 2013 10:21:11 -0800

On Wed, Nov 6, 2013 at 10:05 AM, Julian Reschke <[email-masked]> wrote:
[snip]
> If the client has no reliable way to find out what links are there it'll be
> essentially restricted to edit those that it created itself.
>

This is not a problem I intend to solve... largely because I have no
need to solve it. For one set of use cases I have, there is no need to
discover established links, and for the remaining set, the data
formats used already have ways of exposing whatever links the server
wishes to expose.

That said, have a concrete suggestion?

- James

> Well yes, it includes more parameters, but what I'm mainly concerned with
> parameters that we don't know yet.
>
> Best regards, Julian

---

From: Julian Reschke <[email-masked]>
Date: Wed, 06 Nov 2013 10:31:15 -0800

> That said, have a concrete suggestion?

Maybe have a keyword for the "Prefer" header field that instructs the 
server to return *all* links upon GET?

Best regards, Julian

---

From: James M Snell <[email-masked]>
Date: Wed, 6 Nov 2013 11:56:15 -0800

http://www.ietf.org/id/draft-snell-link-method-07.txt

Per Julian's suggestion, accommodates all target attributes, deals
with 2xx response codes, handles use of the anchor attribute to
override the context IRI. Also, deals with equivalence checking for
IRIs.

- James

On Wed, Nov 6, 2013 at 10:31 AM, Julian Reschke <[email-masked]> wrote:
>>> be
> Maybe have a keyword for the "Prefer" header field that instructs the server
> to return *all* links upon GET?
>
> Best regards, Julian
>
>

---

From: "Manger, James H" <[email-masked]>
Date: Thu, 7 Nov 2013 12:15:11 +1100

> override the context IRI. Also, deals with equivalence checking for

The root cause of the arguments about which link attributes are "significant" is that 1 link syntax is being used for 2 distinct purposes.

1. With the LINK method, a Link header provides a complete link to add.

2. With the UNLINK method, a Link header provides criteria for matching existing links to remove.
 
The Link header is designed to provide a complete link. It is not designed to convey criteria for matching links. It can approximately serve the latter purpose if you add a rule. Possible rules are:
A) "a link matches only if every attribute is exactly the same"; or
B) "a link matches if the attributes provided match, regardless of any other attribute is has"; or
C) "a link matches if the values and presence of 6 specific attributes match (rel, hreflang, ...)".

A better design would be to acknowledge that specifying a link and specifying criteria for matching links are different things. That could be reflected by defining an Unlink header to hold matching criteria. We could drop the UNLINK method and just include Link and Unlink headers when using the LINK method.

The Unlink header could use a syntax like Link; probably with rule B (all attribute in the Unlink value must match, but a link still matches if it has additional attributes); perhaps with an optional extra=false attribute meaning links with additional attributes do not match.

--
James Manger

---

From: Graham Klyne <[email-masked]>
Date: Thu, 07 Nov 2013 09:38:05 +0000

> The Unlink header could use a syntax like Link; probably with rule B (all attribute in the Unlink value must match, but a link still matches if it has additional attributes); perhaps with an option…

I had a similar problem when reading the updated draft: it's not clear what an 
UNLINK actually removes.

I'm uncertain about whether this is the right response, but it seems like a 
plausible approach to me.  I kinda like the idea that it would allow links to be 
changed (remove+add) atomically.

#g
--

---

From: Graham Klyne <[email-masked]>
Date: Thu, 07 Nov 2013 09:25:00 +0000

> significant. I'll add a few more examples)

FWIW, a recent W3C note (not standard) suggests use of anchor, intended to allow 
some refinement of the intended referent of a provenance link, but I don't yet 
know of any implementations:

   http://www.w3.org/TR/prov-aq/
   http://www.w3.org/TR/prov-aq/#resource-accessed-by-http

#g
--

---

From: James M Snell <[email-masked]>
Date: Thu, 7 Nov 2013 08:52:12 -0800

Definitely appreciate the feedback but I'm definitely -1 on the idea
of inventing a new "Unlink" request header. It's just not necessary. I
also don't believe matching rules are required. The UNLINK will match
if all the attributes provided match all the attributes of an
established link. It doesn't need to be more complicated than that.

---

From: "Manger, James H" <[email-masked]>
Date: Fri, 8 Nov 2013 14:54:43 +1100

> established link. It doesn't need to be more complicated than that.

So to change the title associated with an existing link I need to do an UNLINK request to remove the existing one, then a separate LINK request to add the new one. I probably need a 3rd request: an initial GET (or HEAD) to get all the attributes of the old link so I can remove it.

Since I need separate UNLINK and LINK requests, modifying the title cannot be atomic. Ouch.

If I want to remove all rel=alternate links I can’t send 1 request with "Unlink: rel=alternate", but I need to read all existing links, select those with the rel of interest, then replay all those links in an UNLINK request (with an If-Match header in case there were other concurrent changes).

If a link has 2 rel values I assume I need to include both to remove the link. Do they have to be in the same order or does rel="alternate stylesheet" match rel="stylesheet alternate". I wonder what an extraneous space in a rel value would do? The link is likely to work, but an UNLINK request will probably fail.

If I GET an HTML doc that has <link>s, I hope it includes all the attributes of those links otherwise my attempt to remove a link will fail. I hope I can translate HTML attribute values into HTTP header parameter values (doing that RFC2231 paramname*=%-escaped stuff) otherwise I cannot remove links.

If an XML <link> element has an xmlns attribute I assume I don’t translate it to an HTTP Link header parameter when doing an UNLINK request. Is it obvious which XML attributes to include and exclude?

I think splitting Link changes into separate LINK and UNLINK requests is a significant flaw. To fix that you need a separate way to express link removal (eg an Unlink HTTP header is one option), and that way would be more useful with a more lenient matching rule.

--
James Manger

> > The root cause of the arguments about which link attributes are
> "significant" is that 1 link syntax is being used for 2 distinct
> purposes.
> >
> > The Link header is designed to provide a complete link. It is not
> designed to convey criteria for matching links. It can approximately
> serve the latter purpose if you add a rule. Possible rules are:
> > A better design would be to acknowledge that specifying a link and
> specifying criteria for matching links are different things. That could
> be reflected by defining an Unlink header to hold matching criteria. We
> could drop the UNLINK method and just include Link and Unlink headers
> when using the LINK method.
> >
> > The Unlink header could use a syntax like Link; probably with rule B
> (all attribute in the Unlink value must match, but a link still matches
> if it has additional attributes); perhaps with an optional extra=false
> attribute meaning links with additional attributes do not match.
> >
> >
> > --
> > James Manger