Re: What is a Version?

Am 11.03.2026 um 06:42 schrieb Nico Williams:
> ...
>> 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.

Both are resources. Both can have URIs. What "version" refers to I don't 
care at the moment.

> 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

(why not send Location: and leave the choice of the URI to the server?)

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

That might be a URI template. I still don't see why we can't leave that 
to the server.

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

No. I think you're conflating (or I am confused by) what the version of 
the Value field is. It is *certainly* not the version but an identifier 
for the version, no?

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

See above. We need to understand what "the version" refers to. Is it the 
version of a resource, or a *name* for the version of a resource.

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

What is a "first-class URI"???


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

Sorry, I don't follow. An origin server can expose a URI for whatever it 
wants to.

- the bytes 5000--- of the "current" representation of a resource
- the same for a "previous version (per etag)
- etc etc

It *can* do all of that if it wants to.

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

A "version" resource can by anything the author of the specs wants it to 
be (modulo potential naming confusion). It could be a commit, it could 
be part of a commit, it could be a resource at the time of a specfic 
commit, it could be the diff between two commits etc.

It would be confusing though to call all of these version.

Maybe we should look at Git[hub|lab] and discuss what kind of resources 
it exposes over HTTP. I believe that would make things clearer.

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

Opt-in? How does this work with caches?

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

Yes, absolutely. For instance, the response to GET might contain 
something useful :-)

> 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

That's not uncommon.

> and wouldn't build an index from strong or weak ETags of _those_ sorts,
> and dereferencing URIs for those wouldn't be very useful.

Let's ignore weak etags for now.

"useful" is a bit subjective. It might not be useful to your use case of 
course.

Having a URI for "the representation of the resource when it (the 
representation) had this etag" could be useful when looking at the 
history of a resource. FWIW, we have a response field for that in HTTP.

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

Yes. But I'm not sure how this needs to relate to Etags. Yes, it could.

Let's see

  
https://github.com/httpwg/http-extensions/commit/a8977020455250ce2aeb99ba150ab2e90b85dff5

That gives you the HTML representation of a commit.

  
https://github.com/httpwg/http-extensions/commit/a8977020455250ce2aeb99ba150ab2e90b85dff5.patch

That gives you the actual commit. (text plain)

Adding the path in the repo to the URI gives you the representation of 
the resource at the time of the commit.

So github assigns to all kinds of informations specific URIs.

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

If you have an identifier for something, why not assign it a URI, such a 
URN?

Best regards, Julian

Received on Thursday, 12 March 2026 17:12:08 UTC