Re: What is a Version?

On Tue, Mar 10, 2026 at 03:45:06PM +0100, Julian Reschke wrote:
> Am 10.03.2026 um 03:01 schrieb Michael Toomim:
> > 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
> > ...
> 
> I *believe* I said "a version is a resource no matter whether it has a
> (HTTP) URI (yet).

I'm curious about the Version: value as a URI not of the resource itself
but of a resource akin to a "commit object" in a VCS.  I suspect that's
what Michael was referring to.

One could construct a version URI from the version -if it's not already
a URI-, as if it was relative to the same origin as the resource it
versions, yes?  That would make sense to me.

  GET /foo

  200 Ok
  Version: v1.2

and then one could construct a URI to the version resource v1.2 as
something like ${origin}/versions/v1.2 or similarly.  Presumably the
`/versions/` part of the local-part I threw in there could be discovered
via a well-known resource?

In this conception the Version: is a time coordinate but also part of a
URI that can be dereferenced.

I can see this being useful.  E.g., for a VCS (think Git) one could GET
a commit, branch, or tag (or other "ref") object by first resolving a
Version: to a URI.

> > In all three, a version is a thing you dereference -- a resource at a
> > URL.  If it's missing, 404 is natural.
> 
> A version is something for which you can obtain a presentation if it has as
> a URI. If it has a HTTP URL, you can do a GET.

Oh?  So Version: values _can_ be URIs but don't have to be?

> (Nitpicking: in theory, you can use HTTP GET to obtain a representation of a
> representation of any resource with URI if the server supports that)

That could be interesting for (weak?) ETags where ETags are "versions"
and dereferenceable.

> > Second, [...]
> 
> This just means that resources can evolve over time, and that there a two
> types validators which you can use for conditional requests (caching,
> minimizing payloads, pipe-lined range requests, avoiding conflicts when
> updating).
> 
> Whether the "predecessors" can always can be called "version" isn't relevant
> for HTTP. Note that the server can *assign* URIs to these predecessors using
> the Location field.

How?  By putting the version into the URI of the resource.  But not as
first-class URIs for the "versions" themselves.

> > 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`.
> 
> ...but we could.

Not without camping on the URI local-part and q-param design space that
belongs to the application.

But in the case of Version: there is the possibility of there being a
resource that corresponds to the version itself rather than the
versioned resource.  E.g., a commit, branch, or tag in a VCS can be a
version resource.  I'm curious about this case.

> > 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
> 
> In practice, you can't define new fields that support conditional requests
> (unless you control both ends and all intermediaries). For conditional
> reads, that would be harmless (no optimizations), for range requests and
> write conflict prevention it would be a major problem.

You could look before jumping.

> A version *is* a resource. It may not have a URI, but it still is a
> resource.

In some cases it would be desirable for a URI to be available somehow.

I use hashes of the resource's contents as strong ETags, and things like
{filesystem ID, inode number, generation number} as weak ETags.  I don't
and wouldn't build an index from strong or weak ETags of _those_ sorts,
and dereferencing URIs for those wouldn't be very useful.

But if in some app I were using Git commit hashes as (strong) ETags then
I _would_ want an index by ETag and would want the commit resources to
be dereferenceable, and then I'd need the ETags to be URIs _or_ URIs to
be discoverable for them.

> > 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.

Given a non-URI version it should suffice to have a way to discover a
URI for it.

Nico
-- 

Received on Wednesday, 11 March 2026 05:42:33 UTC