POST request to LDPCv to create new

Specification

Delta

With Fedora API Specification:

With Memento Specification:


Other questions

LDPCv Example Response


# GET request to LDPCv
curl http://localhost/rest/a/fcr:versions -H "Accept: application/link-format" -v

< HTTP/1.1 200 OK
< Date: Thu, 21 Jun 2017 00:06:50 GMT
< Server: Apache
< Content-Type: application/link-format
< Allow: GET, HEAD, OPTIONS, POST, PATCH, DELETE
< Accept-Post: text/turtle,text/rdf+n3,text/n3,application/rdf+xml,application/n-triples,application/ld+json,multipart/form-data,application/sparql-update
< Accept-Patch: application/sparql-update
< Connection: close

<http://localhost/rest/a>;rel="original timegate",
<http://localhost/rest/a/fcr:versions>
; rel="self";type="application/link-format"
; from="Tue, 20 Jun 2016 18:02:59 GMT"
; until="Wed, 09 Apr 2017 20:30:51 GMT",
<http://localhost/rest/a/fcr:versions/20160620180259356>; rel="memento";datetime="Tue, 20 Jun 2016 18:02:59 GMT",
<http://localhost/rest/a/fcr:versions/version_1>; rel="memento";datetime="Fri, 06 Jan 2017 18:50:11 GMT",
<http://localhost/rest/a/fcr:versions/20170409203051112>; rel="memento";datetime="Wed, 09 Apr 2017 20:30:51 GMT",


Example Interactions to Version a Resource or a Tree

# 1 - Create LDPRm of single resource
1) curl -XPOST /a/fcr:versions -H "Depth: 0"
  a) Create LDPRm /a/fcr:versions/20170919080311 in LDPCv
2) GET /a/fcr:versions/20170919080311
  </a/fcr:versions/20170919080311> ldp:contains </a/b>
3) GET /a
  </a> ldp:contains </a/b>

# 2 - Create LDPRm of tree
1) curl -XPOST /a/fcr:versions -H "Depth: infinity"
  a) Create LDPRm /a/fcr:versions/20170919080311
  b) Create LDPRm /a/b/fcr:versions/20170919080311
2) GET /a/fcr:versions/20170919080311
  </a/fcr:versions/20170919080311> ldp:contains </a/b>
3) GET /a
  </a> ldp:contains </a/b>

Note: if in example 2 the LDPRm were to have relationship:
</a/fcr:versions/20170919080311> ldp:contains </a/b/fcr:versions/20170919080311>
there would still be multiple parents containing

How does delete behave when multiple LDPRs (a LDPRv and a LDPRm) both ldp:contains the same child? What happens if you delete the LDPRm?

Handling Deletion of Referenced Resources / Mementos

Approach 1 - Prevent deletion

1) Given two resources, /a and /b, where:
</a> dc:related </b>

2) Create a version of /a with `POST /a/fcr:versions`, which creates LDPRm:
/a/fcr:versions/20170919162455

3) Delete /b
< HTTP/1.1 412 Precondition failed
< Date: Tue, 19 Sep 2017 19:55:15 GMT
< Content-Type: text/plain
< Content-Length: 77
< Server: Jetty(9.2.3.v20140905)
Cannot delete resource with incoming relationships from immutable resources.

Approach 2 - Allow deletion, ignore referential integrity

1) Given two resources, /a and /b, where:
</a> dc:related </b>

2) Create a version of /a with `POST /a/fcr:versions`, which creates LDPRm:
/a/fcr:versions/20170919162455

3) Delete /b
< HTTP/1.1 204


4) Get /a
</a> dc:related </b>


5) Get /b
< HTTP/1.1 410 Gone

Accept-Datetime Negotiation Example


Given a LDPRv with two mementos
* Rv => LDPRv, fedora:lastModified = 2017-09-13T20:11:31.291Z
* M1 => LDPRm, memento:datetime = 2017-09-08T18:01:33.535Z
* M0 => LDPRm, memento:datetime = 2017-09-04T09:20:12.030Z

1) GET Rv with no Accept-Datetime
Returns Rv as a LDPRv response.
2) GET Rv "Accept-Datetime: Thu, 1 Jan 2016 00:00:00 GMT" (prior to resource creation)
Response 404 not found
3) GET Rv "Accept-Datetime: Wed, 06 Sep 2017 00:00:00 GMT" (Between M0 and M1)
Returns M0 as a LDPRm response, with Content-Location referencing M0
4) GET Rv "Accept-Datetime: Sun, 10 Sep 2017 00:00:00 GMT" (Between M1 and Rv)
Return M1 as a LDPRm response, with Content-Location referencing M1
5) GET Rv "Accept-Datetime: Sat, 16 Sep 2017 00:00:00 GMT" (after Rv)
Returns Rv as a LDPRv response.
6) GET Rv "Accept-Datetime: Fri, 08 Sep 2017 18:01:33 GMT" (Exact match)
Return M1 as a LDPRm response, with Content-Location referencing M1


To summarize:
1) If no Accept-Datetime is provided, then the LDRPv is returned
2) If Accept-Datetime is provided, then the nearest LDPRm with a Memento-Datetime < than requested time, or LDPRv with created time < than requested time is returned.

Immutable LDPRms and Relaxing Referential Integrity

Fcrepo/Memento defines a past version of a LDPRm (aka a memento) as a fixed representation of the original LDPR at the time the version was created. However, a memento can be incorrectly modified in the following scenario, given memento M of original resource O, and another resource R:

  1. M contains relation dc:related to R
  2. Delete resource R
  3. Modeshape automatically removes dc:related relation from M
  4. M no longer matches O at the time that M was created.

This is because modeshape fedora maintains referential integrity - if a resource is deleted, all references to that resource are removed as well.

To address this, requirements for referential integrity would be relaxed for mementos such that they could continue to refer to the deleted resource. This means that mementos could have triples that reference objects that no longer exist.

This would come with some implications:

Two options for how to handle this would include:

  1. When an LDPRm is created from an LDPRv, all references to modeshape nodes would be converted to URIs. Since they would no longer be node references, they would not be cleaned up.
  2. Instead of storing a LDPRm as a LDPRS, it could be stored as a RDF serialization of the LDPRS stored to a binary.

Versions will be of individual resources, versus tree snapshots

In Fedora 4, when a version of a resource is created, a snapshot of it and the entire tree of child resources it contains is captured.  Moving ahead, the proposed design would instead only create a version of the requested resource, stopping there rather than versioning its child resources.  The resource would be copied as it is and links to other resources would remain intact.

For example, 

1) Create resources </a> and </a/b> as versionable resources (LDPRvs)
2) Create LDPRm of </a>
  Produces LDPRm </a/fcr:versions/20170919080311> in LDPCv
3) GET LDPRm </a/fcr:versions/20170919080311>, which returns:
  </a/fcr:versions/20170919080311> ldp:contains </a/b>
4) GET LDPRv /a
  </a> ldp:contains </a/b>
5) No LDPRm was created for </a/b>


Implications:

Draft Tickets

Add versioning response headers to LDPRv HEAD/GET responses - 

The following headers should be added to responses to HEAD and GET requests to LDPRv's only when the resource is versioned (has the http://fedora.info/definitions/fcrepo#VersionedResource type):

See Pattern 1.2 in https://tools.ietf.org/html/rfc7089#page-18 for details.

Support Datetime negiotation for LDPRvs

Implement support for datetime negotiation for the retrieval of previous versions of a resource as follows:

Add versioning headers for LDPRm HEAD/GET responses

Responses to LDPRm HEAD and GET requests must include headers as outlined below. A resource is a LDPRm if it is of type http://fedora.info/definitions/fcrepo#VersionedResource

Support OPTIONS request on LDPRms

Response to include header 'Allow: GET, HEAD, OPTIONS, DELETE'

Prevent modification requests to LDPRm

PATCH/POST/PUT requests should all return 405 responses

DELETE -  If a resource is deleted from the repository, it appears as if all triples across the repository that have that resource as an object will get removed.  Even in a versioned resource.  According to the API spec, mementos need to be immutable.  This particular behavior of cleaning up will have to change where mementos are concerned.  

PUT requests to LDPRv (work in progress)

See https://fcrepo.github.io/fcrepo-specification/#httpput

If a Accept-Datetime is provided on a regular PUT request to an LDPRv

POST request to LDPCv to create LDPRm

Update POST to LDPCv to include support for versioning headers.  In practice, the LDPCv for object with uri <http://localhost/rest/a> would be <http://localhost/rest/a/fcr:versions>

See: https://fcrepo.github.io/fcrepo-specification/#ldpcvpost

Remove Support for Slug Header on POST to LDPCv

Delete a LDPCv

See: https://fcrepo.github.io/fcrepo-specification/#ldpcvdelete


Delete a LDPRv

(this one might not actually be a ticket, since the behavior, though not totally correct, is in line with what we're targeting.)

DELETE of a LDPR is part of the fedora implementation currently, and will stay part of it.  Per discussion on the fedora-tech list, linking the lifecycle of a LDPR and it's corresponding LDPRm's is okay. When the LDPRv is deleted, the mementos will also be deleted.   

There is the concern about deleting LDPRs and LDPRm's that are referenced by other resources or versions of resources. 

Implement application/link-format for TimeMaps

See: https://fcrepo.github.io/fcrepo-specification/#general-3

Requests to an LDPCv/TimeMap for a LDPRv must support a "application/link-format" response type, as shown in the example https://tools.ietf.org/html/rfc7089#page-37 

HEAD / GET on LDPCv

Enable Versioning on a new LDPR

A PUT or POST request to create an object will make a resource versionable if it includes header Link: rel="type" with type of http://fedora.info/definitions/fcrepo#VersionedResource

  1. A LDPR will be created as a LDPRv with the versioning type.

  2. A LDPCv will be created

  3. A LDPRm will be generated, contained by the LDPCv.

The newly created LDPCv:

Enable Versioning on an Existing LDPR

Note: this is still under discussion since an empty PUT to an LDPR may not be valid.

A PUT request to an Existing LDPR will make a resource versionable if it includes header Link: rel="type" with type of http://fedora.info/definitions/fcrepo#VersionedResource

  1. The versioning type will be added to the LDPR, making it a LDPRv.

  2. A LDPCv will be created for the LDPRv

  3. A LDPRm will be generated, contained by the LDPCv.

Restore a LDPRm

Discusssion of the details for this feature are still ongoing at https://github.com/fcrepo/fcrepo-specification/issues/217

 

Answered questions