Cool URI for Semantic Web is a very good reading to understand W3C TAG position on what URI are.
Broadly speaking, a URI can represent two type of Resources:
1. Web Document such as Web pages, images, etc. (which is referred to as “Inforamtion Resources” in AWWW)
2. Real World Objects (which is referred to as “Things”).
According to W3C guidelines [AWWW], an URI must not represent two different resources/things. Since a Person is not a web page (though that web page may be describing about the person), they must not be represented by a same URI. We need two URIs. In Cool URI for Semantic Web W3C recommends to create URIs in two ways.
(1) Hash URI
This is a document URI + #somestring.
Since any HTTP client strips strings after #, the request sent from the client to the server will be the document URI, so there is no problem in getting the document out of hashed URI.
For example, suppose the identifier that identifies alice was http://example.com/alice#thing, then the URI that goes over the wire will be http://example.com/alice and it is OK to get HTML back since without frangment, it is another URI.
(2) 303 Redirect
Another approach is to create an abstract identifier that identifies the thing, and use 303 redirect to a document (by Location: response header), which may in turn do content negotiation. (Note that the result of the content negotiation must be an equivalent resource.)
Example:
Let http://xri.net/=nat be the ID of a thing.
Then, when requested in GET, it should 303 redirect to a URI of a default web document of =nat with link header describing metadata location.
What about URI based OpenID?
Now, let us think about OpenID in general.
The classic type of OpenID is the Web Page, typically, his home page. This URI is dubbed to be an id of this person as well. This clearly is a violation of [AWWW] principle. Perhaps putting fragment would somewhat solve the issue but it will have serious usability implication.
The second type is YADIS enabled OpenID, i.e., YADIS ID. (e.g., Yahoo! and mixi.)
In this case, the GET to the OpenID usually derives 200 OK with X-XRDS-Location: header. 2xx response code is reserved for Web Documents, so this also violates [AWWW]. In OpenID 2.1, hopefully, we will reference XRD 1.0 so that it will be changed to 303. If one is using his blog or home page URI as OpenID, he should include fragment but it is a pretty bad user interface-wise.
The third type is XRI.
In this case, 302 redirect is used to serve the default document with X-XRDS-Location: header*1. Thus, it is also violating [AWWW]. Instead, it should have been 303 instead of 302*2. In XRI 3.0, it will be 303 redirect with link header, so it will exactly be as in Cool URI for Semantic Web.
Some other thoughts
To save the extra round trip mandated by 303 redirect, it would probably be a good practice to define a path addition to OpenID to create the XRD address, e.g., /+xrd. In the XRI 2.0 HXRI spec, it is ?_xrd_r=application/xrds+xml, but adding /+xrd is a much more appealing way of doing it. After all, <Service> in a XRD is signifying the relationship, and the path component is a selector of the relevant <Service>. So, an XRD corresponding to @free*nat may look like:
<?xml version=”1.0″ encoding=”UTF-8″?>
<XRD xmlns=”http://xri.net/$xrd*($v*2.0)”>
<CanonicalID>@!1ED4.9ED5.8267.FB80!F2B3.EAAA.6509.55F6</CanonicalID>
<Service>
<ProviderID>@!7F6F.F50.A4E4.1133</ProviderID>
<Type>http://oasis-open.org/xri/xrd-1_0</Type>
<Path>(+xrd)</Path>
<URI>http://xri.net/@free*nat?_xrd_r=application/xrds+xml</URI>
</Service>
<Service>
<ProviderID>@!7F6F.F50.A4E4.1133</ProviderID>
<Type>http://openid.net/signon/1.0</Type>
<Path>(+login)</Path>
<URI priority=”2″>http://authn.freexri.com/authentication/</URI>
<URI priority=”1″>https://authn.freexri.com/authentication/</URI>
</Service>
<Service>
<ProviderID>@!7F6F.F50.A4E4.1133</ProviderID>
<Type>xri://+i-service*(+contact)*($v*1.0)</Type>
<Path>(+contact)</Path>
<URI>http://contact.freexri.com/contact/</URI>
</Service>
<Service>
<ProviderID>@!7F6F.F50.A4E4.1133</ProviderID>
<Type>xri://+i-service*(+forwarding)*($v*1.0)</Type>
<Path>(+index)</Path>
<MediaType match=”default”/>
<URI append=”qxri”>http://forwarding.freexri.com/forwarding/</URI>
</Service>
</XRD>
*1 At the time of spec writing, there were no trace of link: header, so this custom header was created.
*2 I kind of remember that there actually was a discussion in the XRI TC whether we should be using 303 or 302, and decided to use 302 because at the time, many browsers did not support 303.