A quick note on using partial URLs in my hypothetical JSON-based API.
In my sketch of a RESTful API for St Ouses, I used a lot of
relative URLs ending with slashes. This is the style preferred when
there is a database-driven web server generating the content. When
using static files it is more convenient to use URLs ending with
something.json
Here is an example of a Cat
entity using ‘file-ish’ URLs:
{
"href": "doomshadow.json",
"aloofness": 72,
"kits": {
"href": "doomshadow-kits.json"
"items": [
{"href": "../kits/boppinjay.json", name": "Boppinjay"},
{"href": "../kits/quinto.json", name": "Quinto"},
],
"more": {
"href": "doomshadow-kits-page2.json"
}
}
}
If the URL this was retrieved from was
file://path/to/cats/doomshadow.json
, then the URL of the collection
is file://path/to/cats/doomshadow-kits.json
. This comes from
stripping off everything after the last slash in the original URL and
substituting doomshadow-kits.json
.
Similarly, the URL of Boppinjay is
file://path/to/kits/boppinjay.json
: after stripping off
doomshadow-kits.json
from the collection URL, the ..
means we
drop cats
, and then we add kits/boppinjay.json
.
One thing that causes occasional confusion is that the rules for
resolving URLs are similar but not identical to those for resolving
relative file names. When resolving a URLs, the client does not know
whether cats
is a file or a directory; creating the absolute URL is
entirely a string-manipulation process. This makes it important to
not forget to end URLs with a slash if they are intended to be
‘directory-ish’.
One reason for including a self-link in all entities (e.g., the href
attribute on the outermost object in the example) is to make
resolution of interior URLs less ambiguous. We had trouble with a
REST server that had its own ideas about which resources should have
slashes at the end of their URLs and as a convenience to sloppy
clients would redirect from http://example.com/foo/bar/
to
http://example.com/foo/bar
if it thought the resource bar
was
file-ish rather than directory-ish. When interpreting a relative URL
baz/quux/
found in the entity it returns, should the client start
with the redirected-to URL http://example.com/foo/bar
(resulting in
http://example.com/foo/baz/quux/
because bar
gets stripped)? Or
use the URL it originally requested, resulting in
http://example.com/foo/bar/baz/quux/
? Including the canonical URL in the entity is intended to insulate us from this confusion.