- From: Michael Toomim <toomim@gmail.com>
- Date: Mon, 9 Mar 2026 16:01:11 -1000
- To: HTTP Working Group <ietf-http-wg@w3.org>, Braid <braid-http@googlegroups.com>
Hey all,
After surveying the different approaches to Versioning in HTTP for draft
-04, I'm realizing there's an important design question for the group here:
=== Q. "What is a Version in HTTP?" ===
Back in October 2024, Julian Reschke said "a version is a HTTP
resource". This definition implied that, for instance, if a version
doesn't exist, we could return 404:
https://lists.w3.org/Archives/Public/ietf-http-wg/2024OctDec/0172.html
This is interesting. Credit to Julian for recognizing the impact of
this question, and suggesting we work to define how these basic concepts
work in HTTP.
When I surveyed the existing versioning approaches in -04, I found two
distinct models:
First, in WebDAV Versioning, Memento, and Link Relations, a version is
itself a resource with its own URI:
- In WebDAV Versioning (RFC 3253), a "version resource" is an
immutable HTTP resource at a server-assigned URL, created when a
"version-controlled resource" is checked in. You GET the version
at its own URL.
- In Memento (RFC 7089), a "Memento" (URI-M) is a resource that
encapsulates a prior state of an "Original Resource" (URI-R). It
has its own URI, and you navigate to it via a TimeGate Resource.
- In Link Relations for Version Navigation (RFC 5829), the link
relation types (predecessor-version, successor-version) assume
you're navigating between version resources, each with its own URI.
In all three, a version is a thing you dereference -- a resource at a
URL. If it's missing, 404 is natural.
Second, we have the Last-Modified and ETag headers, and the Version and
Parents headers proposed in this draft. Instead of version being a
resource with a URI, these simply identify a resource at a *point in
time*. The version is a "coordinate of a resource." Last-Modified and
ETag use coordinate as a condition for a request:
- Last-Modified:
GET /doc
If-Unmodified-Since: Tue, 15 Oct 2024 12:00:00 GMT
- ETag:
GET /doc
If-Match: "abc5"
This draft extends that model by letting the coordinate select a
representation directly:
GET /doc
Version: "abc5"
or:
GET /doc
Parents: "abc4"
This is analogous to how Range requests work. When a client sends
`Range: bytes 500-1000`, it isn't requesting a different resource. The
range is a coordinate within the resource. We do not give ranges their
own URIs, such as `https://example.com/bytes/500-1000` or
`urn:bytes:500-1000`.
Thus, it appears there are two models of "versioning" in HTTP:
1. A version is a HTTP resource
2. A version is a coordinate of a HTTP resource, in time
So the question for the group: What is the right model for HTTP?
What is a version?
My own view is that the coordinate model is the right foundation. It's
simpler, it composes naturally with existing HTTP semantics like
conditional requests and Range, and it doesn't require minting new URIs.
But crucially, the two models are not incompatible -- the coordinate
model can serve as a foundation that the resource model is built on top of:
1. Memento already combines both models. The Memento TimeGate maps a
"coordinate" of time into a "version resource." You give it a
wallclock time, and it gives you back a URI for the resource at
that time.
2. This versions-04 draft can be extended to URIs, by registering
a "Version-Type" with IANA that expresses version coordinates as
URIs, e.g. `Version: "https://example.com/doc^abc123"`.
So if we adopt the coordinate model, applications that need version
resources can still build that on top. The reverse isn't as clean --
if we start from "a version is a resource with a URI", then simple
coordinates like a wallclock time or an opaque version string need to be
encoded into URIs, e.g.
"urn:wallclock:Tue,%2015%20Oct%202024%2012:00:00%20GMT", which works
against the simplicity that HTTP headers already give us.
I'd like to hear the group's thoughts on this framing before draft -05.
Thanks!
Michael
Received on Tuesday, 10 March 2026 02:01:19 UTC