This specification is an attempt to reconcile the semantics and client patterns of [[!LDP]], the versioning requirements of Fedora repositories, and the well-established version identification and navigation scheme delineated in the Memento specification.

Terminology

LDP-R:
A Linked Data Platform Resource. This may be an LDP RDF Source or an LDP Non-RDF Source.
LDP-Rm:
A LDP-R that is a version of another resource LDP-Rv. LDP-Rm are identified by Memento URI-M and contained by LDP-Cv.
LDP-Rv:
A LDP-R that is versioned.Synonymous with Memento URI-R.
LDP-C:
A Linked Data Platform Container.
LDP-Cv:
A Linked Data Platform Version Container.
URI-R:
A type of versioned resource defined in the Memento framework.
URI-M:
A type of resource that is defined in the Memento framework representing a version of a given URI-R.
TimeGate:
A type of resource defined in the Memento framework providing Accept-Datetime -varied negotiation of versions of an URI-R.
TimeMap:
A type of resource defined in the Memento framework that contains a machine-readable listing of URI-Ms connected to a given URI-R.

Versioned Resources (LDP-Rv)

General

A versioned resource is indicated by an interaction model TBD. It otherwise follows the relevant [[!LDP]] specification with the additional behaviors below.

HTTP GET

Common HTTP Request Headers

Link@rel="type" of the URI of the versionable resource interaction model TBD

Common HTTP Response Headers

Link@rel="timemap" to LDP-Cv - this indicates that the resource is versioned Link@rel="timegate" to something, if links to itself it MUST respect Accept-Datetime per Memento. OPTIONAL header that indicates the resource will mint a version with a header, perhaps Vary-Post/Vary-Put; lack of this header indicates that explicit minting if available is advertised via OPTIONS on the LDP-Cv

HTTP Headers for LDP-R that are also TimeGate

Request Headers

Accept-Datetime, per Memento

Response Headers

Vary: Accept-Datetime, per Memento

HTTP HEAD

See:

Version Resources (LDP-Rm Mementos)

General

When a LDP-R is created with a Link header indicating versioning, it is created as both an LDP Resource and a Memento: a LDP-Rm. LDP-Rm SHOULD be invariant: While they may be deleted, they SHOULD NOT be modifiable once created.

HTTP DELETE

DELETE is optional. If DELETE is supported, the Fedora/[[LDP]] server is responsible for all behaviors implied by the containment of the LDP-Rm.

HTTP GET

MUST be supported, as is the case for all LDP-R.

HTTP Response Headers

Link@rel="canonical original" indicating the versioned LDP-Rv Link@rel="timegate" Link@rel="timemap version-history" indicating the LDP-Cv Link@rel="next memento" Link@rel="previous memento" Memento-Datetime

HTTP Response Headers for LDP-NR?

Ought a variant header be provided to indicate that the description, if available, is a timegate or not? It is not strictly necessary: Regardless of how they are synchronized, the [[LDP]] server would be able to identify the relevant version of the LDP-R descriptor. On the other hand: if the LDP-Rv has iana:describedby, all LDP-Rm versionOf LDP-Rv should have a iana:describedby.

HTTP HEAD

MUST be supported.

HTTP Response Headers

HTTP OPTIONS

MUST be supported. Always Allow: GET, HEAD, OPTIONS as per [[LDP]]. MAY Allow: DELETE if clients can remove a version from the version history.

HTTP PATCH

SHOULD NOT be supported.

HTTP POST

MUST NOT be supported.

HTTP PUT

OPTIONAL. SHOULD NOT be supported. Subject to same constraints as PUT to update, further requires Memento headers. Discourage, discourage.

Version Containers (LDP-Cv)

General

When a LDP-R is created with a Link header indicating versioning, a version container (LDP-Cv) is created that contains Memento-identified resources (LDP-Rm) capturing the current state of the described LDP-R. The LDP-Cv is both a TimeMap per [[!RFC7089]] (Memento) and a Container. The [[LDP]] impl MUST indicate TimeMap in the same way it indicates the Container interaction model of the resource (headers, inserted rdf:type, etc). The LDP-Cv MUST respond to GET Accept: application/link-format as indicated in [[!RFC7089]] section 5 and specified in [[RFC6690]] section 7.3.

Non-normative: The application/link-format representation is not required to include all statements in the LDP-Cv graph.

HTTP DELETE

Optional, SHOULD remove the versioning interaction model from the original resource.

HTTP GET

HTTP Request Headers

HTTP Response Headers

Link@rel="type" to indicate Timemap

HTTP HEAD

HTTP Response Headers

HTTP OPTIONS

MUST Allow: GET, HEAD, OPTIONS as per LDP. MAY Allow: DELETE if the versioning behavior is removable by deleting the LDP-Cv. See for requirements on DELETE if supported. MAY Allow: PATCH if the LDP-Cv has mutable properties. See for requirements on PATCH if supported. MAY Allow: POST if versions are explicitly minted by a client. See for requirements on POST if supported.

HTTP PATCH

OPTIONAL. Discourage. MUST NOT modify containment triples if supported.

HTTP POST

PTIONAL. If a LDP-Cv Allow: POST, POST should be understood to create a new LDP-Rm contained by the LDP-Cv, reflecting the state of the LDP-Rv at the time of the POST. If supported, and all LDP-Rm statements are server-managed, Accept-Post SHOULD indicate that no request body is accepted ("Accept-Post: */*; p=0.0" has minimal conflict with LDP), and POST with a request body SHOULD respond with 4xx and a link to an appropriate constraints document (see LDP 4.2.1.6). As per LDP, any resource created via POST, in this case a LDP-Rm) should be advertised in the response's Location header.

If a LDP-Cv accepts POST with a request body, it SHOULD respect a Memento-Datetime request header to mint the URI-M. Absent this header, it MUST use the current time.

Non-normative note: If LDP-Cv implementations do not Allow: POST, the constraints document indicated in Link@rel="constrainedby" for the LDP-Cv should describe the versioning mechanism. Disallowing POST suggests that the [[LDP]] server will manage LDP-Rm creation; see 7.2.1

HTTP PUT

OPTIONAL. If an implementation accepts PUT, it SHOULD reject created URIs that are not URI-m. It MUST respond to rejected request bodies as specified in LDP. LDP-Cv MUST reflect the range of times indicated by contained LDP-Rm.

Non-normative: An implementation that accepts PUT is not required to validate content.

Vary-Post/Vary-Put

When Post/Put to a resource optionally mints an identified version, the resource indicates it with Vary-Post/Vary-Put with the name of the request header indicating it. When a LDP-Cv supports Post/Put with a body, and allows client-specification of URI-M datetime, Vary-Post/Vary-Put: Memento-Datetime.

Implementation Patterns

Introduction

This is a non-normative section describing the way the normative specification might be applied to discoverable versioning patterns. If an implementation of a LDP-Cv does not support POST to mint versions, that is advertisable (MUST be) via OPTIONS, etc. Presumably the implementation would automatically mint versions, but this is ancillary to this specification- the contract is simply with how the LDP-Rm's would be discovered, and how they should act. Following the example of Memento, it would be useful to outline such implementation in non-normative sections down here, but first things first.

LDP-Rm Creation Patterns

Server-Managed LDP-Rm Creation (ajs6f)

Upon POST/PUT/PATCH to the LDP-R/URI-R, a new LDP-Rm/URI-M is created, contained in the version container. This LDP-Rm/URI-M is the version of the original LDP-R/URI-R that was just created.

Client-Managed LDP-Rm Creation, Server-Managed Content (barmintor)

A LDP-Rm/URI-M is created on POST to the LDP-Cv. The LDP-Cv has a constraints document indicating that it does not accept a request body/entity on POST. a. Use a separate request to create the LDP-Rm, for example by posting an empty body. b. Use a header on the original creation interaction to request a new LDP-Rm. c. Use Memento-Datetime as request header to provide datetime of the state to create the new LDP-Rm from, combined with Vary-Post on the LDP-Cv

Client-Managed LDP-Rm Creation, Client-Managed Content (azaroth42)

A LDP-Rm/URI-M is created on POST/PUT to the LDP-Cv, with an entity body. This pattern is the most open, least server managed, but could be important particularly for migration from other systems into spec compatible systems. Use Case: A web archive that manages its descriptive metadata and the HTML NonRdfSources, which have been gathered over the last 20 years by heritrix. Use case 2: Have previous RdfSources from previous systems that manage versioning (such as Marmotta) and need to migrate those Mementos. Plus C from above :)

Responses from GET requests to the LDP-R/URI-R include a Link@rel=’version-history’ pointing to the LDP-Cv as well as a Link@rel="timemap" to the same LDP-Cv.

LDP Considerations

Advertising default behaviors in server constraints document

If the [[LDP]] server allows reuse of URIs after deletion Does this undermine the meaning of the version history?

If the LDP-Rv contains its LDP-Cv This pattern will make it impossible to identify previous versions of a deleted resource.

LDP-Cv as a DirectContainer Minimizing header inspection for read-only clients with http://purl.org/dc/terms/hasVersion or similar.

Memento Considerations

If the LDP-Cv/TimeMap is also the TimeGate Responses from GET requests to the version container (LDP-Cv) will vary depending on the presence or absence of an Accept-Datetime header in the request.

Acknowledgments

Thanks to Aaron Birkland, Adam Soroka, Andrew Woods, Anonymous, Ben Armintor ,Bethany Seeger, Jared Whiklo, Joshua Westgard, LDP-Next, Rob Sanderson, Sergio Fernández, Tom Johnson