forked from fcrepo/fcrepo-specification
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
1056 lines (1008 loc) · 49.7 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html lang="en">
<head>
<title>Fedora API Specification</title>
<meta charset='utf-8'>
<meta name="description" content="Fedora API Specification">
<script src='https://www.w3.org/Tools/respec/respec-w3c-common'
async class='remove'></script>
<script class='remove'>
var respecConfig = {
specStatus: "unofficial",
shortName: "fedora-api",
includePermalinks: true,
editors: [
{ name: "Ben Armintor",
company: "Columbia University",
companyURL: "http://library.columbia.edu/"},
{ name: "Esmé Cowles",
company: "Princeton University",
companyURL: "https://library.princeton.edu"},
{ name: "Daniel Lamb",
company: "Islandora Foundation",
companyURL: "http://islandora.ca/"},
{ name: "Simeon Warner",
company: "Cornell University",
companyURL: "http://www.cornell.edu/"},
{ name: "Andrew Woods",
company: "DuraSpace",
companyURL: "http://duraspace.org/"}
],
edDraftURI: "https://fcrepo.github.io/fcrepo-specification/",
testSuiteURI: "https://github.com/fcrepo/fcrepo-tcks",
wg: "Fedora Specification Working Group",
wgURI: "https://wiki.duraspace.org/display/FEDORAAPI/Fedora+Specification",
wgPublicList: "https://groups.google.com/forum/#!forum/fedora-community",
otherLinks: [{
key: "Contributors",
data: [
{
value: "Aaron Birkland, Johns Hopkins"
},
{
value: "Aaron Coburn, Amherst College"
},
{
value: "Sergio Fernández, Redlink"
},
{
value: "Tom Johnson, Digital Public Library of America"
},
{
value: "Nick Ruest, York University"
},
{
value: "Rob Sanderson, The Getty Trust"
},
{
value: "Bethany Seeger, Amherst College"
},
{
value: "Adam Soroka, Smithsonian Institution"
},
{
value: "Joshua Westgard, University of Maryland"
},
{
value: "Jared Whiklo, University of Manitoba"
}
]
},{
key: "Repository",
data: [
{
value: "Github",
href: "https://github.com/fcrepo/fcrepo-specification"
},
{
value: "Issues",
href: "https://github.com/fcrepo/fcrepo-specification/issues"
},
{
value: "Commits",
href: "https://github.com/fcrepo/fcrepo-specification/commits"
}
]
}],
maxTocLevel: 3,
logos: [{src: "http://fedora.info/assets/fedora_logo.png",
alt: "Fedora Repository logo",
width: 202,
height: 70}],
overrideCopyright: "<p class='copyright'>This document is licensed under a <a class='subfoot' href='https://creativecommons.org/licenses/by/4.0/' rel='license'>Creative Commons Attribution 4.0 License</a>.</p>"
};
</script>
</head>
<body>
<section id='abstract' class='informative'>
<h2>Introduction</h2>
<p>
This specification refines the semantics and interaction patterns of [[LDP]] in order
to better serve the specific needs of those interested in implementing repositories
for durable access to digital data. Additionally, this specification contains:
</p>
<ul>
<li>
a reconciliation of [[LDP]] and the well-established version identification and
navigation scheme delineated in the [[RFC7089]] (Memento) specification,
</li>
<li>
interaction patterns for use with binary fixity information,
</li>
<li>
integration with the <a href="https://www.w3.org/wiki/WebAccessControl">Web Access Control proposal,</a>
</li>
<li>
and a design for the publication of asynchronous events emitted from an implementation.
</li>
</ul>
<p>
The goal of this specification is to define the behaviors of Fedora server implementations in order to
facilitate interoperability with client applications. Although Fedora servers are not necessarily drop-in replacements
for one another, a client developed against this specification should work against any Fedora server with little modification.
Some implementations may be unable to provide all features described in this document due to conscious design decisions, but
at least the method of rejection for requests against such features is defined.
</p>
</section>
<section id="conformance">
<p>
A conforming <b>Fedora server</b> is a conforming [[!LDP]] 1.0 server except where described in this document
that also follows the rules defined by Fedora in <a href="#resource-management"></a>,
<a href="#resource-versioning"></a>, <a href="#resource-authorization"></a>, and <a href="#notifications"></a>.
</p>
</section>
<section id="terminology">
<h2>Terminology</h2>
<p>
Terminology is based on W3C's Linked Data Platform 1.0 [[LDP]] and Memento [[RFC7089]].
<dl>
<dt><dfn>LDPR</dfn>:</dt>
<dd>
A Linked Data Platform Resource as defined in [<a href="https://www.w3.org/TR/ldp/#dfn-linked-data-platform-resource">LDP</a>].
This may be an <a href="https://www.w3.org/TR/ldp/#dfn-linked-data-platform-rdf-source">LDP RDF Source</a> (<a>LDP-RS</a>) or an
<a href="https://www.w3.org/TR/ldp/#dfn-linked-data-platform-non-rdf-source">LDP Non-RDF Source</a> (<a>LDP-NR</a>).
</dd>
<dt><dfn>LDP-RS</dfn>:</dt>
<dd>
An <a>LDPR</a> whose state is fully represented in RDF as defined in
[<a href="https://www.w3.org/TR/ldp/#dfn-linked-data-platform-rdf-source">LDP</a>].
</dd>
<dt><dfn>LDP-NR</dfn>:</dt>
<dd>
An <a>LDPR</a> whose state is not represented in RDF as defined in
[<a href="https://www.w3.org/TR/ldp/#dfn-linked-data-platform-non-rdf-source">LDP</a>].
</dd>
<dt><dfn>LDPRv</dfn>:</dt>
<dd>
An <a>LDPR</a> that is simultaneously a Memento <a>URI-R</a>.
</dd>
<dt><dfn>LDPRm</dfn>:</dt>
<dd>
An <a>LDPR</a> that is simultaneously a Memento <a>URI-M</a>.
</dd>
<dt><dfn>LDPC</dfn>:</dt>
<dd>
A collection of linked documents or information resources as defined in
[<a href="https://www.w3.org/TR/ldp/#dfn-linked-data-platform-container">LDP</a>].
</dd>
<dt><dfn>LDPCv</dfn>:</dt>
<dd>
A version container: an <a>LDPC</a> that is simultaneously a Memento <a>TimeMap</a>.
</dd>
<dt><dfn>LDP-contained</dfn>:</dt>
<dd>
The relationship binding an <a>LDPC</a> to <a>LDPR</a>s whose lifecycle it controls and is aware of as defined in
[<a href="https://www.w3.org/TR/ldp/#dfn-containment">LDP</a>].
</dd>
<dt><dfn>URI-R</dfn>:</dt>
<dd>
A type of versioned resource defined in [<a href="https://tools.ietf.org/html/rfc7089#section-1.1">Memento</a>].
</dd>
<dt><dfn>URI-M</dfn>:</dt>
<dd>
A type of resource that is defined in [<a href="https://tools.ietf.org/html/rfc7089#section-1.1">Memento</a>]
as representing a version of a given <a>URI-R</a>.
</dd>
<dt><dfn>TimeGate</dfn>:</dt>
<dd>
A type of resource defined in [<a href="https://tools.ietf.org/html/rfc7089#section-1.1">Memento</a>] providing
<code>Accept-Datetime</code>-varied negotiation of versions of an <a>URI-R</a>.
</dd>
<dt><dfn>TimeMap</dfn>:</dt>
<dd>
A type of resource defined in [<a href="https://tools.ietf.org/html/rfc7089#section-1.1">Memento</a>] that
contains a machine-readable listing of <a>URI-M</a>s associated to a given <a>URI-R</a>.
</dd>
</dl>
</section>
<section id="resource-management">
<h2>Resource Management</h2>
<section id="general">
<h2>General</h2>
<p>
If a <code>Link: rel="type"</code> header specifies an <a>LDP-NR</a> interaction model
(<code>ldp:NonRDFSource</code>), then the server SHOULD handle subsequent requests
to the newly created resource as if it is a <a>LDP-NR</a>.
([[!LDP]] <a href="https://www.w3.org/TR/ldp/#ldpc-post-createrdf">5.2.3.4 extension</a>)
</p>
<section id="LDPC">
<h2>LDP Containers</h2>
<p>
Implementations MUST support the creation and management of [[!LDP]] Containers.
LDP Direct Containers MUST NOT permit <code>ldp:contains</code> as their membership-predicate
and requests that would do so MUST fail with 409 Conflict.
([[!LDP]] <a href="https://www.w3.org/TR/ldp/#ldpdc-containtriples">5.4.1.4 expansion</a>)
</p>
</section>
</section>
<section id="httpPATCH">
<h2>HTTP PATCH</h2>
<p>
Any <a>LDP-RS</a> MUST support <code>PATCH</code> ([[!LDP]]
<a href="https://www.w3.org/TR/ldp/#ldpr-HTTP_PATCH">4.2.7</a> MAY becomes MUST).
[[!sparql11-update]] MUST be an accepted content-type for <code>PATCH</code>. Other content-types (e.g. [[ldpatch]])
MAY be available. If an otherwise valid HTTP <code>PATCH</code> request is received that attempts to add statements to a
resource that a server disallows (not ignores per [[!LDP]]
<a href="https://www.w3.org/TR/ldp/#ldpr-put-replaceall">4.2.4.1</a>), the server MUST fail
the request by responding with a 4xx range status code (e.g. 409 Conflict). The server MUST
provide a corresponding response body containing information about which statements could
not be persisted. ([[!LDP]] <a href="https://www.w3.org/TR/ldp/#ldprs-put-failed">4.2.4.4</a> SHOULD becomes
MUST). In that response the restrictions causing such a request to fail MUST be described in a resource
indicated by a <code>Link: rel="http://www.w3.org/ns/ldp#constrainedBy"</code> response header per
[[!LDP]] <a href='https://www.w3.org/TR/ldp/#ldpr-gen-pubclireqs'>4.2.1.6</a>.
A successful <code>PATCH</code> request MUST respond with a 2xx status code; the specific code in the 2xx
range MAY vary according to the response body or request state.
</p>
<section id="httpPATCH-ixn-models">
<h3>Interaction models</h3>
<p>
The server MUST disallow a <code>PATCH</code> request that would change the LDP interaction model of a
resource to a type that is not a subtype of the current resource type. That request MUST be
rejected with a 409 Conflict response.
</p>
</section>
</section>
<section id="httpPOST">
<h2>HTTP POST</h2>
<p>
Any <a>LDPC</a> MUST support <code>POST</code> ([[!LDP]] <a href="https://www.w3.org/TR/ldp/#ldpr-HTTP_POST">4.2.3</a> /
<a href="https://www.w3.org/TR/ldp/#ldpc-HTTP_POST">5.2.3</a>). The default interaction model that
will be assigned when there is no explicit Link header in the request MUST be recorded
in the constraints document referenced in the <code>Link: rel="http://www.w3.org/ns/ldp#constrainedBy"</code>
header ([[!LDP]] <a href='https://www.w3.org/TR/ldp/#ldpr-gen-pubclireqs'>4.2.1.6</a> clarification).
Any <a>LDPC</a> MUST support creation of <a>LDP-NR</a>s on <code>POST</code> ([[!LDP]]
<a href="https://www.w3.org/TR/ldp/#h-ldpc-post-createbins">5.2.3.3</a> MAY becomes MUST). On creation of an
<a>LDP-NR</a> an implementation MUST create an associated <a>LDP-RS</a> describing that <a>LDP-NR</a>
([[!LDP]] <a href="https://www.w3.org/TR/ldp/#h-ldpc-post-createbinlinkmetahdr">5.2.3.12</a> MAY becomes MUST).
</p>
<section id="httpPOSTLDPNR">
<h2>LDP-NRs</h2>
<p>
A HTTP <code>POST</code> request that would create a <a>LDP-NR</a> and includes a <code>Digest</code> header
(as described in [[!RFC3230]]) for which the instance-digest in that header does not
match that of the new <a>LDP-NR</a> MUST be rejected with a 409 Conflict response.
</p>
<p>
A HTTP <code>POST</code> request that includes an unsupported <code>Digest</code> type (as described
in [[!RFC3230]]), SHOULD be rejected with a 400 Bad Request response.
</p>
<p class='informative'>
Implementations may support <code>Content-Type: message/external-body</code> extensions for
request bodies for HTTP <code>POST</code> that would create <a>LDP-NR</a>s.
This content-type requires a complete <code>Content-Type</code> header that includes the location
of the external body, e.g <code>Content-Type: message/external-body; access-type=URL; URL=\"http://www.example.com/file\"</code>,
as defined in [[!RFC2017]]. Requirements for this interaction are detailed in <a href="#external-content">External LDP-NR Content</a>.
</p>
</section>
</section>
<section id="httpPUT">
<h2>HTTP PUT</h2>
<p>
When accepting a <code>PUT</code> request against an extant resource, an HTTP <code>Link: rel="type"</code>
header MAY be included. If that type is a value in the LDP namespace and is not either a
current type of the resource or a subtype of a current type of the resource, the request MUST be
rejected with a 409 Conflict response. If the type in the Link header is a subtype of a current type
of the resource, and has an interaction model assigned to it by [[!LDP]], then the resource MUST
be assigned the new type and the interaction model of the resource MUST be changed to the
interaction model assigned to the new type by [[!LDP]].
</p>
<section id="httpPUTLDPNR">
<h2><a>LDP-NR</a>s</h2>
<p>
Any <a>LDP-NR</a> MUST support <code>PUT</code> to replace the binary content of that resource.
</p>
<p>
A HTTP <code>PUT</code> request that includes a <code>Digest</code> header (as described
in [[!RFC3230]]) for which any instance-digest in that header does not match the instance
it describes, MUST be rejected with a 409 Conflict response.
</p>
<p>
A HTTP <code>PUT</code> request that includes an unsupported <code>Digest</code> type (as described
in [[!RFC3230]]), SHOULD be rejected with a 400 Bad Request response.
</p>
<p class='informative'>
Implementations may support <code>Content-Type: message/external-body</code> extensions for
request bodies for HTTP <code>PUT</code> that would create <a>LDP-NR</a>s.
This content-type requires a complete <code>Content-Type</code> header that includes the location
of the external body, e.g <code>Content-Type: message/external-body; access-type=URL; URL=\"http://www.example.com/file\"</code>,
as defined in [[!RFC2017]]. Requirements for this interaction are detailed in <a href="#external-content">External LDP-NR Content</a>.
</p>
</section>
<section id="httpPUTLDPRS">
<h2>LDP-RSs</h2>
<p>
Any <a>LDP-RS</a> MUST support <code>PUT</code> to update statements that are not server-managed triples
(as defined in [[!LDP]] 2). [[!LDP]] <a href="https://www.w3.org/TR/ldp/#ldpr-put-replaceall">4.2.4.1</a>
and <a href="https://www.w3.org/TR/ldp/#ldprs-put-servermanagedprops">4.2.4.3</a> remain in effect. If an
otherwise valid HTTP <code>PUT</code> request is received that attempts to add statements to a resource that a
server disallows (not ignores per [[!LDP]] <a href="https://www.w3.org/TR/ldp/#ldpr-put-replaceall">4.2.4.1</a>),
the server MUST fail the request by responding with a 4xx range status code (e.g. 409 Conflict). The server
MUST provide a corresponding response body containing information about which statements could not be
persisted. ([[!LDP]] <a href="https://www.w3.org/TR/ldp/#ldprs-put-failed">4.2.4.4</a> SHOULD becomes MUST).
In that response the restrictions causing such a request to fail MUST be described in a resource indicated
by a <code>Link: rel="http://www.w3.org/ns/ldp#constrainedBy"</code> response header per [[!LDP]]
<a href='https://www.w3.org/TR/ldp/#ldpr-gen-pubclireqs'>4.2.1.6</a>.
</p>
</section>
<section id="httpPUTcreate" class="informative">
<h2>Creating resources with HTTP PUT</h2>
<p>
An implementation MAY accept HTTP <code>PUT</code> to create resources ([[!LDP]]
<a href="https://www.w3.org/TR/ldp/#ldpr-put-create">4.2.4.6</a>). Behavior regarding
containment or non-containment of resources created with HTTP <code>PUT</code> is
not defined by [[!LDP]] or this specification.
</p>
</section>
</section>
<section id="httpGET">
<h2>HTTP GET</h2>
<p>
When the request is to the <a>LDP-RS</a> created to describe a <a>LDP-NR</a>, the response MUST include
a <code>Link: rel="describes"</code> header referencing the <a>LDP-NR</a> in question, as defined
in [[!RFC6892]].
</p>
<section id="additionalPreferValues">
<h2>Additional values for the <code>Prefer</code> header</h2>
<p>
In addition to the requirements of [[!LDP]], an implementation MAY support the value
<code>http://www.w3.org/ns/oa#PreferContainedDescriptions</code> and SHOULD support the value
<code>http://fedora.info/definitions/fcrepo#PreferInboundReferences</code> for the
<code>Prefer</code> header when making <code>GET</code> requests on <a>LDPC</a> resources:
</p>
<ul>
<li>
<code>http://www.w3.org/ns/oa#PreferContainedDescriptions</code>:
Requires a server to include representations of any contained resources in the response,
as defined in [[!annotation-vocab]].
</li>
<li>
<code>http://fedora.info/definitions/fcrepo#PreferInboundReferences</code>:
Requires a server to include triples from any <a>LDP-RS</a> housed in that server that
feature the requested resource as RDF-object.
</li>
</ul>
</section>
<section id="httpGETLDPRS">
<h2><a>LDP-RS</a>s</h2>
<p>
Responses to <code>GET</code> requests that apply a <code>Prefer</code> request header to any
<a>LDP-RS</a> MUST include the <code>Preference-Applied</code> response header as defined in
[[!RFC7240]] <a href='https://tools.ietf.org/html/rfc7240#section-3'>section 3</a>.
</p>
</section>
<section id="httpGETLDPNR">
<h2><a>LDP-NR</a>s</h2>
<p>
<code>GET</code> requests to any <a>LDP-NR</a> MUST correctly respond to the <code>Want-Digest</code> header
defined in [[!RFC3230]].
</p>
<p class='informative'>
Non-normative note: Given the use of checksums to validate content integrity, the digest values
should be calculated instead of cached.
</p>
</section>
</section>
<section id="httpHEAD">
<h2>HTTP HEAD</h2>
<p>
The <code>HEAD</code> method is identical to <code>GET</code> except that the server
MUST NOT return a message-body in the response, as specified in [[!RFC7231]]
<a href='https://tools.ietf.org/html/rfc7231#section-4.3.2'>section 4.3.2</a>.
The server MUST send the same <code>Digest</code> header in the response as it would
have sent if the request had been a <code>GET</code> (or omit it if it would have been
omitted for a <code>GET</code>). In other cases, the server SHOULD send the same
headers in response to a <code>HEAD</code> request as it would have sent if the
request had been a <code>GET</code>, except that the payload headers (defined in [[!RFC7231]]
<a href='https://tools.ietf.org/html/rfc7231#section-3.3'>section 3.3</a>) MAY be omitted.
</p>
</section>
<section id="httpDELETE">
<h2>HTTP DELETE</h2>
<p>
The <code>DELETE</code> method is optional per [[!LDP]] <a href='https://www.w3.org/TR/ldp/#ldpr-HTTP_DELETE'>section
4.2.5</a> and this specification does not require Fedora servers to implement it. When a Fedora server supports this method,
in addition to the requirements imposed on <a>LDPR</a>s within containers outlined in [[!LDP]]
<a href='https://www.w3.org/TR/ldp/#ldpc-HTTP_DELETE'> section 5.2.5</a>, it must also follow the additional behavior outlined
below.
</p>
<section id="httpDELETEDepth">
<h3>Depth Header</h3>
<p>
A Feodra server MAY support the <code>Depth</code> header, as defined in [[!RFC4918]] <a href='https://tools.ietf.org/html/rfc4918#section-10.2'> section
10.2 </a>. Implementations MAY choose not to support all of the header's values and MUST reject a request containing an unsupported <code>Depth</code>
value with a 400 (Bad Request). Implementations MUST define their own default behavior if a Depth header is not present.
</p>
<p>
If a server supports recursive <code>DELETE</code>, that recursion MUST be reckoned along the <code>ldp:contains</code> axis linking contained resources.
</p>
</section>
</section>
<section id='external-content'>
<h3>External Binary Content</h3>
<blockquote id='message-external-body-variability' class='informative'>
Non-normative note: Variability among client types and locations may mean that LDP-NR
content is addressed in ways that are external to the Fedora server but not resolvable
by all clients. This specification describes the use of <code>Content-Type: message/external-body</code>
values to signal, on POST or PUT, that the Fedora server should should not consider the
request entity to be the LDP-NR's content, but that a <code>Content-Type</code> value will signal a
name or address at which the content might be retreived. The <code>url</code>
and <code>local-file</code> type values motivate this specification, but a Fedora server
may support any type parameters per the requirements for advertisement and
rejection specified here.
</blockquote>
<p id='message-external-body-accept-post'>
Fedora servers that support LDP-NR with <code>message/external-body</code>
MUST advertise that support in the <code>Accept-Post</code> response
header for each supported <code>type</code> parameter of supported <code>Content-Type</code> values.
</p>
<p id='message-external-body-unsupported-type'>
Fedora servers receiving requests that would create or update a LDP-NR
with a <code>message/external-body</code> with an unsupported
<code>type</code> parameter MUST respond with HTTP 415 UNSUPPORTED MEDIA TYPE.
In the case that a Fedora server does not support external LDP-NR content, all
<code>message/external-body</code> messages must be rejected with HTTP 415.
</p>
<p id='message-external-body-response-headers'>
Fedora servers receiving requests that would create or update a LDP-NR
with a <code>message/external-body</code> MUST NOT accept the
request if it cannot guarantee all of the response headers required
by the LDP-NR interaction model in this specification.
</p>
<p id='external-content-content-location'>
LDP-NR GET and HEAD responses SHOULD include a <code>Content-Location</code> header with a URI
representation of the location of the external content if the Fedora server is proxying
the content.
</p>
<p id='external-content-expires'>
Per [[!RFC1521]], all <code>Content-Type: message/external-body</code> values
MAY include an <code>expiration</code> parameter. Fedora servers receiving requests that
would create or update a LDP-NR with a <code>message/external-body</code> content
type SHOULD respect the <code>expiration</code> parameter, if present, by copying
content. If the <code>expiration</code> parameter cannot be accommodated, the request MUST be rejected
with a 4xx or 5xx status code. Following [[!LDP]] <a href="https://www.w3.org/TR/ldp/#ldpr-gen-pubclireqs">4.2.1.6</a>
and <a href="https://www.w3.org/TR/ldp/#ldprs-put-servermanagedprops">4.2.4.3</a>,
4xx responses MUST be accompanied by a <code>Link</code> header
with <code>http://www.w3.org/ns/ldp#constrainedBy</code> relation.
</p>
<section id='external-content-caveats' class='informative'>
<h4>Referenced RDF Content in Mandatory LDP Serializations</h4>
<p>
This specification takes no position on the use of <code>message/external-body</code>
to create or update LDP-RS with ttl or json-ld.
</p>
<h4>Proxied Content vs Redirected Content</h4>
<p>
This specification assumes that clients interested in resolving a <code>type='url'</code>
or other value without the Fedora server as an intermediary (effectively, redirection as opposed
to proxying) will be able to negotiate the <code>Content-Location</code> response header
value from a HEAD request.
</p>
</section>
</section>
</section>
<section id="resource-versioning">
<h2>Resource Versioning</h2>
<section>
<h2>Versioned Resources (<a>LDPRv</a>)</h2>
<section>
<h2>General</h2>
<p>
A versioned resource for this document provides a <a>TimeGate</a> interaction model as
detailed in the Memento specification and indicated by an HTTP header
<code>Link: rel="timegate"</code> referencing itself. It otherwise follows the relevant
[[!LDP]] specification with the additional behaviors below.
</p>
</section>
<section id='httpget'>
<h2>HTTP GET</h2>
<section>
<h2>Request Headers for an LDPRv</h2>
<p>
<code>Accept-Datetime</code>, exactly as per Memento.
</p>
</section>
<section>
<h2>Response Headers</h2>
<p>
At least one <code>Link: rel="timemap"</code> referencing an <a>LDPCv</a>. It is the
presence of this header that indicates that the resource is versioned.
</p>
<p>
<code>Vary: Accept-Datetime</code>, exactly as per Memento.
</p>
</section>
</section>
<section id='httpput'>
<h2>HTTP PUT</h2>
<section id="httpput-general">
<h2>General</h2>
<p>
An <a>LDPRv</a> MAY support <code>PUT</code>. An implementation receiving a <code>PUT</code> request for an
<a>LDPRv</a> MUST both correctly respond as per [[!LDP]] as well as create a new
<a>LDPRm</a> contained in an appropriate <a>LDPCv</a>. The newly-created <a>LDPRm</a>
SHOULD be the version of the <a>LDPRv</a> that was created by the <code>PUT</code> request.
</p>
</section>
<section>
<h2>Request Headers for an LDPRv</h2>
<p>
<code>Accept-Datetime</code>, exactly as per Memento.
</p>
</section>
<section>
<h2>Response Headers</h2>
<p>
At least one <code>Link: rel="timemap"</code> referencing a <a>LDPCv</a>. It is the
presence of this header that indicates that the resource is versioned.
</p>
<p>
<code>Vary: Accept-Datetime</code>, exactly as per Memento.
</p>
</section>
</section>
<section>
<h2>HTTP HEAD</h2>
<p>
See: <a href='#httpget'></a>
</p>
</section>
</section>
<section>
<h2>Version Resources (<a>LDPRm</a>)</h2>
<section>
<h2>General</h2>
<p>
When a <a>LDPR</a> is created with a <code>Link</code> header indicating versioning,
it is created as both an LDP Resource and a Memento: a <a>LDPRm</a>. An <a>LDPRm</a>
MUST be invariant: While it MAY be deleted, it MUST NOT be modified once created.
</p>
</section>
<section>
<h2>HTTP DELETE</h2>
<p>
An implementation MAY support <code>DELETE</code> for <a>LDPRm</a>s. If <code>DELETE</code> is
supported, the server is responsible for all behaviors implied by the LDP-containment
of the <a>LDPRm</a>.
</p>
</section>
<section>
<h2>HTTP GET</h2>
<p>
An implementation MUST support <code>GET</code>, as is the case for any <a>LDPR</a>.
The headers for <code>GET</code> requests and responses on this resource MUST conform
to [[!RFC7089]] (Memento). Particularly it should be noted that the relevant <a>TimeGate</a> for
an <a>LDPRm</a> is the original versioned <a>LDPRv</a>.
</p>
</section>
<section>
<h2>HTTP HEAD</h2>
<p>
An implementation MUST support <code>HEAD</code>.
</p>
</section>
<section>
<h2>HTTP OPTIONS</h2>
<p>
An implementation MUST support <code>OPTIONS</code>. A response to an <code>OPTIONS</code>
request MUST include <code>Allow: GET, HEAD, OPTIONS</code> as per [[!LDP]]. An
implementation MAY include <code>Allow: DELETE</code> if clients can remove a version
from the version history, as noted <a href="#h-http-delete">above</a>.
</p>
</section>
<section>
<h2>HTTP PATCH</h2>
<p>
An implementation MUST NOT support <code>PATCH</code> for <a>LDPRm</a>s.
</p>
</section>
<section>
<h2>HTTP POST</h2>
<p>
An implementation MUST NOT support <code>POST</code> for <a>LDPRm</a>s.
</p>
</section>
<section>
<h2>HTTP PUT</h2>
<p>
An implementation MUST NOT support <code>PUT</code> for <a>LDPRm</a>s.
</p>
</section>
</section>
<section>
<h2>Version Containers (<a>LDPCv</a>)</h2>
<section>
<h2>General</h2>
<p>
When a <a>LDPR</a> is created with a <code>Link</code> header indicating versioning, a
version container (<a>LDPCv</a>) is created that contains Memento-identified resources
(<a>LDPRm</a>) capturing time-varying representations of the associated <a>LDPR</a>. An
<a>LDPCv</a> is both a <a>TimeMap</a> per [[!RFC7089]] (Memento) and an LDP Container.
As a <a>TimeMap</a> an <a>LDPCv</a> MUST conform to the specification for such resources
in [[!RFC7089]]. An implementation MUST indicate <a>TimeMap</a> in the same way it
indicates the Container interaction model of the resource via HTTP headers. An <a>LDPCv</a>
MUST respond to <code>GET Accept: application/link-format</code> as indicated in [[!RFC7089]]
<a href='https://tools.ietf.org/html/rfc7089#section-5'>section 5</a> and specified in
[[!RFC6690]] <a href='https://tools.ietf.org/html/rfc6690#section-7.3'>section 7.3</a>.
</p>
<p>
An implementation MUST NOT allow the creation of an <a>LDPCv</a> that is <a>LDP-contained</a>
by its associated <a>LDPRv</a>.
</p>
<p class="informative">
Non-normative: The <code>application/link-format</code> representation of a <a>LDPCv</a>
is not required to include all statements in the <a>LDPCv</a> graph, only those required
by <a>TimeMap</a> behaviors.
</p>
</section>
<section>
<h2 id='ldpcvdelete'>HTTP DELETE</h2>
<p>
An implementation MAY support <code>DELETE</code>. An implementation that does support
<code>DELETE</code> SHOULD do so by both removing the <a>LDPCv</a> and removing the
versioning interaction model from the original <a>LDPRv</a>.
</p>
</section>
<section>
<h2>HTTP OPTIONS</h2>
<p>
An implementation MUST <code>Allow: GET, HEAD, OPTIONS</code> as per [[!LDP]]. An
implementation MAY <code>Allow: DELETE</code> if the versioning behavior is removable
by deleting the <a>LDPCv</a>. See <a href='#ldpcvdelete'></a> for requirements on
<code>DELETE</code> if supported.
</p>
<p>
An implementation MAY <code>Allow: PATCH</code> if the <a>LDPCv</a> has mutable properties.
See <a href='#ldpcvpatch'></a> for requirements on <code>PATCH</code> if supported.
</p>
<p>
An implementation MAY <code>Allow: POST</code> if versions can be explicitly minted by a
client. See <a href='#ldpcvpost'></a> for requirements on <code>POST</code> if supported.
</p>
</section>
<section>
<h2 id='ldpcvpatch'>HTTP PATCH</h2>
<p>
An implementation MAY <code>Allow: PATCH</code>, but if so, it MUST NOT permit clients
to modify containment triples.
</p>
</section>
<section>
<h2 id='ldpcvpost'>HTTP POST</h2>
<p>
If a <a>LDPCv</a> supports <code>POST</code>, <code>POST</code> SHOULD be understood to
create a new <a>LDPRm</a> contained by the <a>LDPCv</a>, reflecting the state of the
<a>LDPRv</a> at the time of the <code>POST</code>. If supported, but the representation
at the time of version creation can only be that which is current for the <a>LDPRv</a>,
the <code>Accept-Post</code> header of any response from the <a>LDPCv</a> SHOULD indicate
that no request body is accepted via the form <code>Accept-Post: */*; p=0.0</code>, and
that implementation SHOULD respond to any body-containing <code>POST</code> to that
<a>LDPCv</a> with a 415 response and a link to an appropriate constraints document
(see <a href='https://www.w3.org/TR/ldp/#ldpr-gen-pubclireqs'>LDP 4.2.1.6</a>). As per
[[!LDP]], any resource created via <code>POST</code>, in this case a <a>LDPRm</a>)
SHOULD be advertised in the response's <code>Location</code> header.
</p>
<p>
If a <a>LDPCv</a> does accept <code>POST</code> with a request body, it SHOULD respect
a <code>Memento-Datetime</code> request header for the created <a>LDPRm</a>.
Absent this header, it MUST use the current time.
</p>
<p class="informative">
Non-normative note: If an <a>LDPCv</a> does not <code>Allow: POST</code>, the constraints
document indicated in <code>Link: rel="http://www.w3.org/ns/ldp#constrainedBy"</code> for
that <a>LDPCv</a> should describe the versioning mechanism (e.g. by <code>PUT</code> or
<code>PATCH</code> to the <a>LDPRv</a> described by that <a>LDPCv</a>). Disallowing
<code>POST</code> suggests that the [[!LDP]] server will manage all <a>LDPRm</a>
creation; see <a href ="#server-managed">here</a>.
</p>
</section>
</section>
<section>
<h2 class='informative'>Vary</h2>
<p>
When a <code>POST</code> to an <a>LDPCv</a> or <code>PUT</code> or <code>PATCH</code> to
an <a>LDPRv</a> creates a new <a>LDPRm</a>, the response indicates that using a
<code>Vary</code> header as appropriate. When a <a>LDPCv</a> supports <code>POST</code>,
and allows clients to specify a datetime for created <a>URI-M</a>s,
Vary-Post/Vary-Put: Memento-Datetime.
</p>
</section>
<section class="informative">
<h2>Implementation Patterns</h2>
<section>
<h2>Introduction</h2>
<p>
This is a non-normative section describing the way the normative specification might be
applied to implement discoverable versioning patterns. If an implementation of a
<a>LDPCv</a> does not support <code>POST</code> to mint versions, that must be advertised
via <code>OPTIONS</code> as described above. The implementation may automatically mint
versions instead, but that is outside the requirements of this specification. This
document specifies normatively only how <a>LDPCv</a>s and <a>LDPRm</a>s can be
discovered, and how they should act.
</p>
</section>
<section>
<h2><a>LDPRm</a> Creation Patterns</h2>
<section id="server-managed">
<h2>Server-Managed Version Creation</h2>
<p>
Upon <code>PUT</code> or <code>PATCH</code> to the <a>LDPRv</a>, a new <a>LDPRm</a>
is created in an appropriate <a>LDPCv</a>. This <a>LDPRm</a> is the version of the
original <a>LDPRv</a> that was just created.
</p>
</section>
<section id="client-managed">
<h2>Client-Managed Version Creation</h2>
<p>
An <a>LDPRm</a> for a particular <a>LDPRv</a> is created on <code>POST</code> to any
<a>LDPCv</a> associated with that <a>LDPRv</a>. The new <a>LDPRm</a> is contained in
the <a>LDPCv</a> to which the <code>POST</code> was made and features in that
<a>LDPCv</a>-as-a<a>TimeMap</a> . This pattern is more open to manipulation and could
be useful for migration from other systems into Fedora implementations. Responses from
requests to the <a>LDPRv</a> include a <code>Link: rel="timemap"</code> to the same
<a>LDPCv</a> as per [[!RFC7089]] (Memento).
</p>
</section>
</section>
</section>
</section>
<section id="resource-authorization">
<h2>Resource Authorization</h2>
<p>
To configure access control restrictions, implementations MUST follow the recommendations
of [[!SOLIDWEBAC]] with the following additional requirements:
</p>
<section id="solid-ldp-acls">
<h2>ACLs are LDP RDF Sources</h2>
<p>
The linked Access Control List Resource (ACL) for a controlled
resource by a conforming server MUST itself be a LDPRS. This ACL
resource SHOULD be located in the same server as the controlled
resource.
</p>
</section>
<section id="link-rel-acl">
<h2>ACLs are discoverable via Link Headers</h2>
<p>
A conforming server MUST advertise the linked Access Control
List Resource (ACL) for a controlled resource in HTTP responses
with a <code>Link: rel="acl"</code> header. This interaction
pattern is described in [[!WEBAC]] and [!SOLIDWEBAC]].
</p>
</section>
<section id="inheritance">
<h2>Inheritance</h2>
<p>
Inheritance of ACLs as defined in [[!SOLIDWEBAC]] MUST be
reckoned along the <code>ldp:contains</code> axis linking
controlled resources.
</p>
</section>
</section>
<section id="notifications">
<h2>Notifications</h2>
<section class="informative">
<h3>Introduction</h3>
<p>
This section defines when notifications are made available by a Fedora
implementation, the minimal set of data contained in these notifications and how
the data are serialized. Notifications may be emitted synchronously or asynchronously
with the API operations that cause them to be emitted. These notifications are typically
used to support external integrations. The structure of these notifications draws upon the
existing [[activitystreams-core]] and [[ldn]] specifications.
An implementation is free to choose from any transport technology so long as
the notifications conform to what is described in the following sections.
</p>
<p>
Implementers should be aware that some operations cause multiple resources to change.
In these cases, there will be a corresponding notification describing each of the changes.
This is especially true for changes to containment or membership triples. This is also true
if a <code>DELETE</code> operation triggers changes in any contained resources.
</p>
<p>
Consumers of these notifications should not expect a strict ordering of
the events reported therein: the fact that a notification for Event A is received before
a notification for Event B should not imply that Event A occurred before Event B.
Implementations may choose to make further guarantees about ordering.
</p>
<p>
According to the [[activitystreams-core]] specification, it is possible to collect multiple
events into a single notification. This specification makes no restriction on the use of
activity stream collections.
</p>
</section>
<section id="notification-events">
<h3>Notification Events</h3>
<p>
For every resource whose state is changed as a result of an HTTP operation,
there MUST be a corresponding notification made available describing that change.
</p>
</section>
<section id="notification-serialization">
<h3>Notification Serialization</h3>
<p>
The notification serialization MUST conform to the [[!activitystreams-core]] specification.
</p>
<p>
Wherever possible, data SHOULD be expressed using the [[!activitystreams-vocabulary]].
</p>
<p>
Each event described by a notification MUST contain:
</p>
<ul>
<li>The IRI of the resource that was created, modified or deleted</li>
<li>The event type(s), corresponding to the HTTP operation</li>
</ul>
<p>
Each event described by a notification SHOULD contain:
</p>
<ul>
<li>The agent(s) that caused the change to occur</li>
<li>The RDF type(s) of the resource that was changed</li>
<li>The location of the <code>ldp:inbox</code> for the resource that was changed, if such an inbox link exists</li>
</ul>
<p>
Notifications SHOULD NOT contain the entire content of repository resources.
</p>
</section>
<section id="notification-examples" class="informative">
<h3>Examples</h3>
<section id="minimal-notification-example">
<h4>A minimal notification</h4>
<div class="example">
<pre class="json">
{
"@context": "https://www.w3.org/ns/activitystreams",
"id": "urn:uuid:3c834a8f-5638-4412-aa4b-35ea80416a18",
"type": "Create",
"name": "Resource Creation",
"actor": "http://example.org/agent/fedoraAdmin",
"object": {
"id": "http://example.org/fcrepo/rest/resource/path",
"type": [
"ldp:Container",
"ldp:RDFSource"
]
}
}
</pre>
</div>
</section>
<section id="basic-notification-example">
<h4>A basic notification with some additional detail</h4>
<div class="example">
<pre class="json">
{
"@context": [
"https://www.w3.org/ns/activitystreams",
{
"isPartOf": {
"@id": "http://purl.org/dc/terms/date",
"@type": "@id"
}
}
],
"id": "urn:uuid:be29ae69-2134-f1b0-34be-2f91b6d1f029",
"type": "Update",
"name": "Resource Modification",
"published": "2016-07-04T13:46:39Z",
"inbox": "http://example.org/ldn/inbox/path",
"actor": [
{
"id": "#actor0",
"type": "Person",
"name": "fedo raAdmin"
},
{
"id": "#actor1",
"type": "Service",
"name": "APIX-core/0.1"
}
],
"object": {
"id": "http://example.org/fcrepo/rest/resource/path",
"updated": "2016-07-04T13:44:39Z",
"type": [
"ldp:Container",
"ldp:RDFSource",
"http://example.org/type/CustomType"
],
"isPartOf": "http://example.org/fcrepo/rest/"
}
}
</pre>
</div>
</section>
</section>
</section>
<section id="binary-fixity">
<h2>Binary Resource Fixity</h2>
<section id="what-is-fixity" class="informative">
<h2>What is fixity?</h2>
<p>
For the purposes of the following specification, a fixity result is an extract or summary
of some <a>LDP-NR</a> made according to some explicit procedure. Fixity results are taken for the
purpose of comparing different fixity results for the same resource over time, to ensure
a continuity of that resource's identity according to the particular procedure used.
Examples might include:
</p>
<ul>
<li>Checksums like MD5 or SHA1, often used for digital images.</li>
<li><a href="https://www.w3.org/TR/xmldsig-core/">XML Signatures</a></li>
<li>Per-segment results <a href="http://dericed.com/papers/reconsidering-the-checksum-for-audiovisual-preservation/">as used for time-based media</a></li>
</ul>
<p>
This specification describes two fixity verification mechanisms: firstly, as part of
content transmission, to guard against faults in transmission, and secondly, by comparison
to a known or proffered digest value, to monitor for faults in persistence.
</p>
</section>
<section id="transmission-fixity" class="informative">
<h2>Transmission Fixity</h2>
<p>
Transmission fixity may be verified by including a <code>Digest</code> header (defined in
[[RFC3230]]) in <code>POST</code> and <code>PUT</code> requests for <a>LDP-NR</a>s.
</p>
</section>
<section id="persistence-fixity" class="informative">
<h2>Persistence Fixity</h2>
<p>
A client may retrieve the checksum of an <a>LDP-NR</a> by performing a <code>HEAD</code> or
<code>GET</code> request on it with the <code>Want-Digest</code> header (using a <code>HEAD</code>
request allows the client to avoid transferring the entire content when only the checksum is
needed). The <code>Digest</code> header in the response can be used to infer persistence fixity by
comparing it to previously-computed values.
</p>
</section>