Introduction

Forming an absolute URI from a reference URI and a relative path is not simply a matter of concatenating the relative path to the reference URI. RFC3986 specifies the algorithm that must be performed to correctly transform a reference URI and relative path to an absolute URI.

Establishing the base URI

From RFC3986 Section 5.1:

The term “relative” implies that a “base URI” exists against which the relative reference is applied. Aside from fragment-only references (Section 4.4), relative references are only usable when a base URI is known. A base URI must be established by the parser prior to parsing URI references that might be relative.

Thus for any relative URI found within a resource, the base URI of that containing resource must be established. RFC3986 specifies a number of mechanisms for establishing the base URI but the typical mechanism is to use the URI used to retrieve the resource:

If no base URI is embedded and the representation is not encapsulated within some other entity, then, if a URI was used to retrieve the representation, that URI shall be considered the base URI.

Relative Resolution

Resolving the relative URI with reference to the base URI involves a number of steps (consult RFC 3986 Section 5.2 for more detail), but the key step is quoted below:

return a string consisting of the reference’s path component appended to all but the last segment of the base URI’s path (i.e., excluding any characters after the right-most “/” in the base URI path, or excluding the entire base URI path if it does not contain any “/” characters).

Note how the right-most / character has special significance in the application of the resolution algorithm. Any characters to the right of the right-most / character in the base URI are ignored when resolving relative paths.

For example if the base URI of the resource containing a relative URI reference is:

https://api.example.com/hr/employees

and the relative URI embedded in the hr/employees resource is:

...
 "links": [
     {"rel": "self", "href": "./31280"}
 ]
...

then the reference URI to resolve the path relative to is:

https://api.example.com/hr/

Recall the characters after the right-most / character need to ignored, thus the reference path is hr/ not hr/employees, and thus the fully qualified resolved URI of the relative URI is:

https://api.example.com/hr/31280

That’s probably not what was intended, one would imagine the desired fully qualified URI would have been:

https://api.example.com/hr/employees/31280

Due to the base URI not having a trailing slash the relative URI embedded in the resource did not resolve correctly.

It is not called out explicitly in RFC 3986, but the implication of the significance of the right-most / character in the URI resolution algorithm is that if a resource has child resources (let’s call it the parent resource), then the parent resource must have a trailing slash. For example, because there is a resource named: /hr/employees/31280, that implies that resource’s parent must be named: /hr/employees/ not /hr/employees.

Conclusion

A corollary to the significance of the right most / character with regard to resolution of URIs is that ‘parent’ resources must have a trailing slash in their name.

References

  1. Reference Resolution - Uniform Resource Identifier (URI): Generic Syntax: RFC 3986 Section 5
  2. Establishing a Base URI - Uniform Resource Identifier (URI): Generic Syntax: RFC 3986 Section 5.1
  3. Relative Resolution - Uniform Resource Identifier (URI): Generic Syntax: RFC 3986 Section 5.2