W3C

Linked Data Platform 1.0

W3C Working Draft 25 October 2012

This version:
http://www.w3.org/TR/2012/WD-ldp-20121025/
Latest version:
http://www.w3.org/TR/ldp/
Editors:
Steve Speicher, IBM Corporation
Michael Hausenblas, DERI, NUI Galway

Abstract

A set of best practices and simple approach for a read-write Linked Data architecture, based on HTTP access to web resources that describe their state using RDF.

Status of This Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This First Public Working Draft was published by the Linked Data Platform Working Group. This document builds on a W3C Member Submission. All known issues are documented inline as well as in the LDP WG Issue Tracker. If you wish to make comments regarding this document, please send them to public-ldp@w3.org (subscribe, archives). All feedback is welcome.

Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

Table of Contents

1. Introduction

This document describes the use of HTTP for accessing, updating, creating and deleting resources from servers that expose their resources as Linked Data. It provides some new rules as well as clarifications and extensions of the four rules of Linked Data [LINKED-DATA]

1. Use URIs as names for things

2. Use HTTP URIs so that people can look up those names

3. When someone looks up a URI, provide useful information, using the standards (RDF*, SPARQL)

4. Include links to other URIs. so that they can discover more things

The best practices and anti-patterns covered in this document are:

Additionally, it is the intention of this document to enable additional rules and layered groupings of rules, such as additional specifications. The scope is intentionally narrow to provide a set of key rules for reading and writing Linked Data that most, if not all, other specifications will depend on and implementations will support.

2. Terminology

Terminology is based on W3C's Architecture of the World Wide Web [WEBARCH] and Hyper-text Transfer Protocol [HTTP11]

Link
A relationship between two resources when one resource (representation) refers to the other resource by means of a URI.[WEBARCH]
Linked Data
As defined by Tim Berners-Lee. [LINKED-DATA]
Linked Data Platform Resource (LDPR)
HTTP resource that conforms to the simple lifecycle patterns and conventions in this document.
Linked Data Platform Container (LDPC)
LDP resource that also conforms to additional patterns and conventions in this document for managing membership.
Client
A program that establishes connections for the purpose of sending requests. [HTTP11]
Server
An application program that accepts connections in order to service requests by sending back responses. Any given program may be capable of being both a client and a server; our use of these terms refers only to the role being performed by the program for a particular connection, rather than to the program's capabilities in general. Likewise, any server may act as an origin server, proxy, gateway, or tunnel, switching behavior based on the nature of each request. [HTTP11]
CLOSED Better define or just not use the "Basic profile" terminology

2.1 Conventions Used in This Document

Sample resource representations are provided in text/turtle format [TURTLE].

Commonly used namespace prefixes:

	@prefix dcterms: <http://purl.org/dc/terms/>.
	@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
	@prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#>.
	@prefix ldp:      <http://www.w3.org/ns/ldp#>.
	@prefix xsd:     <http://www.w3.org/2001/XMLSchema#>.

3. Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key words must, must not, required, should, should not, recommended, may, and optional in this specification are to be interpreted as described in [RFC2119].

4. Linked Data Platform Resource

Linked Data Platform Resources (LDPRs) are HTTP resources that conform to the simple patterns and conventions in this section. HTTP requests to access, modify, create or delete LDPRs are accepted and processed by LDPR servers. Most LDPRs are domain-specific resources that contain data for an entity in some domain, which could be commercial, governmental, scientific, religious, or other.

Some of the rules defined in this document provide clarification and refinement of the base Linked Data rules [LINKED-DATA], others address additional needs.

The rules for Linked Data Platform Resources address basic questions such as:

The following sections define the rules and guidelines for use of LDPRs.

4.1 General

4.1.1 LDPR servers must at least be HTTP/1.1 conformant servers [HTTP11].
4.1.2 LDPR servers must provide an RDF representation for LDPRs. The subject is typically the LDPR itself.
4.1.3 LDPR servers may host a mixture of LDPRs and non-LDPRs. For example, it is common for LDPR servers to need to host binary or text resources that do not have useful RDF representations.
4.1.4 Clients can access a LDPR using multiple URLs, for example when DNS aliasing is used. A LDPR server must respond to each of those requests using a single consistent URL, a canonical URL, for the LDPR which may be found in the response's Location header and potentially also in the representation of the LDPR. Clients should use that canonical URL to identify the LDPR.
4.1.5 LDPR predicates should use standard vocabularies such as Dublin Core [DC-TERMS], RDF [RDF-PRIMER] and RDF Schema [RDF-SCHEMA], whenever possible. LDPRs should reuse existing vocabularies instead of creating their own duplicate vocabulary terms.
4.1.6 LDPR predicates must use well-known RDF vocabularies as defined in section 4.8 Common Properties wherever a predicate’s meaning matches one of them.
4.1.6.1 LDPRs must use the predicate rdf:type to represent the concept of type. The use of non-standard type predicates, as well as dcterms:type, is discouraged. [DC-RDF]
4.1.7 LDPR representations should have at least one rdf:type set explicitly. This makes the representations much more useful to client applications that don’t support inferencing.
4.1.8 Predicate URIs used in LDPR representations should be HTTP URLs. These predicate URIs must identify LDPRs whose representations are retrievable. LDPR servers should provide an RDF Schema [RDF-SCHEMA] representation of these predicates.
Should properties used in LDPR representations be LDPRs?
4.1.9 LDPR representations must use only the following standard datatypes. RDF does not by itself define datatypes to be used for literal property values, therefore a set of standard datatypes based on [XMLSCHEMA11-2] and [RDF-PRIMER] are to be used:
URIDescription
http://www.w3.org/2001/XMLSchema#booleanBoolean type as specified by XSD Boolean
http://www.w3.org/2001/XMLSchema#dateDate type as specified by XSD date
http://www.w3.org/2001/XMLSchema#dateTimeDate and Time type as specified by XSD dateTime
http://www.w3.org/2001/XMLSchema#decimalDecimal number type as specified by XSD Decimal
http://www.w3.org/2001/XMLSchema#doubleDouble floating-point number type as specified by XSD Double
http://www.w3.org/2001/XMLSchema#floatFloating-point number type as specified by XSD Float
http://www.w3.org/2001/XMLSchema#integerInteger number type as specified by XSD Integer
http://www.w3.org/2001/XMLSchema#stringString type as specified by XSD String
http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteralLiteral XML value as specified by RDF
Should LDBP say that any kind of user-defined simple data type is disallowed?
4.1.10 LDPRs must use at least one RDF triple to represent a link (relationship) to another resource. In other words, having the source resource’s URI as the subject and the target resource’s URI as the object of the triple represent the link (relationship) is enough and does not require the creation of an intermediate link resource to describe the relationship.
4.1.11 LDPR servers may support additional standard representations. These could be other RDF formats, like N3 or NTriples, but non-RDF formats like HTML [HTML401] and JSON [RFC4627] would be likely be common.
Need to normatively reference and recommend JSON-LD
4.1.12 LDPRs may be created, updated and deleted using methods not defined in this document, for example through application-specific means, SPARQL UPDATE, etc. [SPARQL-UPDATE]
4.1.13 LDPR server responses must contain accurate response ETag header values.
Include clarifications and guidance around ETags
Do LDPR versions get managed in a systematic, discoverable way?
sharing binary resources and metadata
Redirection of non-information resources to LDPRs
Adressing more error cases

4.2 HTTP GET

4.2.1 LDPR servers must support the HTTP GET Method for LDPRs.
4.2.2 LDPR servers must provide an text/turtle representation of the requested LDPR.[TURTLE]
4.2.3 LDPR servers should provide a application/rdf+xml representation of the requested LDPR.[RDF-SYNTAX]
Remove application/rdf+xml as a should
4.2.4 In the absence of special knowledge of the application or domain, LDPR clients must assume that any LDPR may have multiple values for rdf:type.
4.2.5 In the absence of special knowledge of the application or domain, LDPR clients must assume that the rdf:type values of a given LDPR may change over time.

4.3 HTTP POST

There are no additional requirements on HTTP POST for LDPRs.

4.4 HTTP PUT

4.4.1 If HTTP PUT is performed on an existing resource, LDPR servers must replace the entire persistent state of the identified resource with the entity representation in the body of the request. The only recognized exception are the properties dcterms:modified and dcterms:creator that are never under client control - LDPR servers must ignore any values of these properties that are provided by the client. Any LDPR servers that wish to support a more sophisticated merge of data provided by the client with existing state stored on the server for a resource must use HTTP PATCH, not HTTP PUT.
Do we need to define server-managed properties or do we leave them to applications?
4.4.2 LDPR clients should use the HTTP If-Match header and HTTP ETags to ensure it isn’t modifying a resource that has changed since the client last retrieved its representation. LDPR servers should require the HTTP If-Match header and HTTP ETags to detect collisions. LDPR servers must respond with status code 412 (Condition Failed) if ETags fail to match if there are no other errors with the request. [HTTP11]
4.4.3 LDPR clients should always assume that the set of predicates for a resource of a particular type at an arbitrary server is open in the sense that different resources of the same type may not all have the same set of predicates in its triples, and the set of predicates that are used in the state of a resource is not limited to any pre-defined set.
4.4.4 LDPR clients should assume that a LDPR server could discard triples whose predicates the server does not recognize or otherwise chooses not to persist. In other words, LDPR servers may restrict themselves to a known set of predicates, but LDPR clients must not restrict themselves to a known set of predicates when their intent is to perform a later HTTP PUT to update the resource.
4.4.5 A LDPR client must preserve all triples retrieved using HTTP GET that it doesn’t change whether it understands the predicates or not, when its intent is to perform an update using HTTP PUT. The use of HTTP PATCH instead of HTTP PUT for update avoids this burden for clients [RFC5789].
4.4.6 LDPR servers may choose to allow the creation of new resources using HTTP PUT.
4.4.7 LDPR servers should allow clients to update resources without requiring detailed knowledge of server-specific constraints. It is common for LDPR servers to put restrictions on representations – for example, the range of rdf:type, datatypes of predicates and number of occurrences of predicates in triples, but servers should minimize those restrictions. In other words, LDPR servers need to enable simple modification of LDPRs. Enforcement of more complex constraints will greatly restrict the types of clients that can modify resources. For some server applications, excessive constraints on modification of resources may be required.

4.5 HTTP DELETE

4.5.1 LDPR servers must remove the resource identified by the Request-URI. After a successful HTTP DELETE, a subsequent HTTP GET on the same Request-URI must result in a 404 (Not found) or 410 (Gone) status code, until another resource is created or associated with the same Request-URI.
4.5.2 LDPR servers may alter the state of other resources as a result of an HTTP DELETE request. For example, it is acceptable for the server to remove triples from other resources whose subject or object is the deleted resource. It is also acceptable and common for LDPR servers to not do this – behavior is server application specific.
Should DELETED resources remain deleted?

4.6 HTTP HEAD

4.6.1 LDPR servers must support the HTTP HEAD method.
4.6.2 LDPR servers must indicate their support for HTTP Methods by responding to a HTTP HEAD request on the LDPR’s URL with the HTTP Method tokens in the HTTP response header “Allow”.

4.7 HTTP PATCH

4.7.1 LDPR servers may implement HTTP PATCH to allow modifications, especially partial replacement, of their resources. [RFC5789] No minimal set of patch document formats is mandated by this document.
4.7.2 LDPR servers should allow clients to update resources without requiring detailed knowledge of server-specific constraints. It is common for LDPR servers to put restrictions on representations – for example, the range of rdf:type, datatypes of predicates and number of occurrences of predicates in triples – but server enforcement of detailed, domain-specific constraints will greatly restrict the types of clients who can update resources.
Can HTTP PATCH be used for resource creation?
changesets as a recommended PATCH format

4.8 Common Properties

This section summarizes some well-known RDF vocabularies that must be used in Linked Data Platform Resources wherever a resource needs to use a predicate whose meaning matches one of these. For example, if a BP resource has a description, and the application semantic of that description is compatible with dcterms:description, then dcterms:description must be used. If needed, additional application-specific predicates may be used. A specification for a domain that is based on BP may require one or more of these properties for a particular resource type. The Range column in the tables below identify the recommended rdfs:range for the properties.

4.8.1 From Dublin Core

URI: http://purl.org/dc/terms/

Property Range/DataType Comment
dcterms:contributor dcterms:Agent
dcterms:creator dcterms:Agent
dcterms:created xsd:dateTime
dcterms:description rdf:XMLLiteral Descriptive text about the resource represented as rich text in XHTML format. should include only content that is valid and suitable inside an XHTML <div> element.
dcterms:identifier rdfs:Literal
dcterms:modified xsd:dateTime
dcterms:relation rdfs:Resource The HTTP URI of a related resource. This is the predicate to use when you don't know what else to use. If you know more specifically what sort of relationship it is, use a more specific predicate.
dcterms:subject rdfs:Resource
dcterms:title rdf:XMLLiteral A name given to the resource. Represented as rich text in XHTML format. should include only content that is valid inside an XHTML <span> element.

The predicate dcterms:type should not be used, instead use rdf:type. [DC-RDF].

4.8.2 From RDF

URI: http://www.w3.org/1999/02/22-rdf-syntax-ns#

Property Range Comment
rdf:type rdfs:Class The type or types of the resource
4.8.3 From RDF Schema

URI: http://www.w3.org/2000/01/rdf-schema#

Property Range Comment
rdfs:member rdfs:Resource
rdfs:label rdfs:Literal Only use this in vocabulary documents, to define the name of the vocabulary term.

5. Linked Data Platform Container

5.1 Informative

This section is non-normative.

Many HTTP applications and sites have organizing concepts that partition the overall space of resources into smaller containers. Blog posts are grouped into blogs, wiki pages are grouped into wikis, and products are grouped into catalogs. Each resource created in the application or site is created within an instance of one of these container-like entities, and users can list the existing artifacts within one. Containers answer some basic questions, which are:

  1. To which URLs can I POST to create new resources?
  2. Where can I GET a list of existing resources?
  3. How is the order of the container entries expressed?
  4. How do I get information about the members along with the container?
  5. How do I GET the entries of a large container broken up into pages?
  6. How can I ensure the resource data is easy to query?

This document defines the representation and behavior of containers that address these issues. The set of members of a container is defined by a set of triples in its representation (and state) called the membership triples. The membership triples of a container all have the same subject and predicate – the objects of the membership triples define the members of the container. The subject of the membership triples is called the membership subject and the predicate is called the membership predicate. In the simplest cases, the membership subject will be the LDPC resource itself, but it does not have to be. The membership predicate is also variable and will often be a predicate from the server application vocabulary or the rdfs:member predicate.

This document includes a set of guidelines for using POST to create new resources and add them to the list of members of a container. This document also explains how to include information about each member in the container’s own representation and how to paginate the container representation if it gets too big.

The following illustrates a very simple container with only three members and some information about the container (the fact that it is a container and a brief title):

Example 1
# The following is the representation of
#    http://example.org/container1
@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.

<http://example.org/container1>
   a ldp:Container;
   dcterms:title "A very simple container";
   rdfs:member
      <http://example.org/container1/member1>,
      <http://example.org/container1/member2>,
      <http://example.org/container1/member3>.

This example is very straightforward - the membership predicate is rdfs:member and the membership subject is the container itself. A POST to this container will create a new resource and add it to the list of members by adding a new membership triple to the container.

Sometimes it is useful to use a subject other than the container itself as the membership subject and to use a predicate other than rdfs:member as the membership predicate, as illustrated below.

Example 2
# The following is the representation of
#   http://example.org/netWorth/nw1/assetContainer
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix o: <http://example.org/ontology/>.

<http://example.org/netWorth/nw1/assetContainer>
   a ldp:Container;
   ldp:membershipSubject <http://example.org/netWorth/nw1>;
   ldp:membershipPredicate o:asset.

<http://example.org/netWorth/nw1>
   a o:NetWorth;
   o:asset
      <http://example.org/netWorth/nw1/assetContainer/a1>,
      <http://example.org/netWorth/nw1/assetContainer/a2>.

The essential structure of the container is the same, but in this example, the membership subject is not the container itself – it is a separate net worth resource. The membership predicate is o:asset – a predicate from the domain model. A POST to this container will create a new asset and add it to the list of members by adding a new membership triple to the container. You might wonder why we didn’t just make http://example.org/netWorth/nw1 a container and POST the new asset directly there. That would be a fine design if http://example.org/netWorth/nw1 had only assets, but if it has separate predicates for assets and liabilities, that design will not work because it is unspecified to which predicate the POST should add a membership triple. Having separate http://example.org/netWorth/nw1/assetContainer and http://example.org/netWorth/nw1/liabilityContainer container resources allows both assets and liabilities to be created.

In this example, clients cannot simply guess which resource is the membership subject and which predicate is the membership predicate, so the example includes this information in triples whose subject is the LDPC resource itself.

5.1.1 Container Member Information
This section is non-normative

In many – perhaps most – applications involving containers, it is desirable for the client to be able to get information about each container member without having to do a GET on each one. LDPC allows servers to include this information directly in the representation of the container. The server decides the amount of data about each member that is provided. Some common strategies include providing a fixed number of standard properties, or providing the entire RDF representation of each member resource, or providing nothing. The server application domain and its use-cases will determine how much information is required.

Continuing on from the net worth example, there will be additional triples for the member resources (assets) in the representation:

Example 3
# The following is the representation of
#	 http://example.org/netWorth/nw1/assetContainer
@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#>.
@prefix ldp:      <http://www.w3.org/ns/ldp#>.
@prefix o:       <http://example.org/ontology/>.

<http://example.org/netWorth/nw1/assetContainer>
   a ldp:Container;
   dcterms:title "The assets of JohnZSmith";
   ldp:membershipSubject <http://example.org/netWorth/nw1>;
   ldp:membershipPredicate o:asset.

<http://example.org/netWorth/nw1>
   a o:NetWorth;
   o:asset
      <http://example.org/netWorth/nw1/assetContainer/a1>,
      <http://example.org/netWorth/nw1/assetContainer/a3>,
      <http://example.org/netWorth/nw1/assetContainer/a2>.

<http://example.org/netWorth/nw1/assetContainer/a1>
   a o:Stock;
   o:value 10000.
<http://example.org/netWorth/nw1/assetContainer/a2>
   a o:Bond;
   o:value 20000.
<http://example.org/netWorth/nw1/assetContainer/a3>
   a o:RealEstateHolding;
   o:value 300000.
5.1.2 Retrieving Only Non-member Properties
This section is non-normative

The representation of a container that has many members will be large. There are several important cases where clients need to access only the non-member properties of the container. Since retrieving the whole container representation to get this information may be onerous for clients and cause unnecessary overhead on servers, it is desired to define a way to retrieve only the non-member property values. Defining for each LDPC a corresponding resource, called the “non-member resource”, whose state is a subset of the state of the container, does this.

The example listed here only show a simple case where only a few simple non-member properties are retrieved. In real world situations more complex cases are likely, such as those that add other predicates to containers, for example providing validation information and associating SPARQL endpoints. [SPARQL-QUERY]

Here is an example requesting the non-member properties of a container identified by the URL http://example.org/container1 and adding the query string ?non-member-properties :

Request:

Example 4
GET /container1?non-member-properties HTTP/1.1
Host: example.org
Accept: text/turtle; charset=UTF-8

Response:

Example 5
HTTP/1.1 200 OK
Content-Type: text/turtle; chartset=UTF-8
ETag: "_87e52ce291112"
Content-Length: 325

@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.

<http://example.org/container1>
   a ldp:Container;
   dcterms:title "A Linked Data Platform Container of Acme Resources";
   ldp:membershipPredicate rdfs:member;
   dcterms:publisher <http://acme.com/>.
5.1.3 Paging
This section is non-normative

It sometimes happens that a container is too large to reasonably transmit its representation in a single HTTP response. This will be especially true if the container representation includes many triples from the representations of its members. A client may anticipate that a container will be too large - for example, a client tool that accesses defects may assume that an individual defect will usually be of sufficiently constrained size that it makes sense to request all of it at once, but that the container of all the defects ever created will typically be too big. Alternatively, a server may recognize that a container that has been requested is too big to return in a single message.

To address this problem, LDPCs may support a technique called Paging. Paging can be achieved with a simple RDF pattern. For each container resource, <containerURL>, we define a new resource <containerURL>?firstPage. The triples in the representation of <containerURL>?firstPage are a subset of the triples in <containerURL> - same subject, predicate and object.

LDPC servers may respond to requests for a container by redirecting the client to the first page resource – using a 303 “See Other” redirect to the actual URL for the page resource.

Continuing on from the member information from the JohnZSmith net worth example, we’ll split the response across two pages. The client requests the first page as http://example.org/netWorth/nw1/assetContainer?firstPage:

Example 6
# The following is the representation of
#    http://example.org/netWorth/nw1/assetContainer?firstPage
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix o: <http://example.org/ontology/>.

<http://example.org/netWorth/nw1/assetContainer>
   a ldp:Container;
   dcterms:title "The assets of JohnZSmith";
   ldp:membershipSubject <http://example.org/netWorth/nw1>;
   ldp:membershipPredicate o:asset.

<http://example.org/netWorth/nw1/assetContainer?firstPage>
   a ldp:Page;
   ldp:pageOf <http://example.org/netWorth/nw1/assetContainer>;
   ldp:nextPage <http://example.org/netWorth/nw1/assetContainer?p=2>.
 
<http://example.org/netWorth/nw1>
    a o:NetWorth;
	o:asset
	<http://example.org/netWorth/nw1/assetContainer/a1>,
	<http://example.org/netWorth/nw1/assetContainer/a4>,
	<http://example.org/netWorth/nw1/assetContainer/a3>,
	<http://example.org/netWorth/nw1/assetContainer/a2>.

<http://example.org/netWorth/nw1/assetContainer/a1>
   a o:Stock;
   o:value 100.00.
<http://example.org/netWorth/nw1/assetContainer/a2>
   a o:Cash;
   o:value 50.00.
# server initially supplied no data for a3 and a4 in this response

The following example is the result of retrieving the representation for the next page:

Example 7
# The following is the representation of
#  http://example.org/netWorth/nw1/assetContainer?p=2
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix o: <http://example.org/ontology/>.

<http://example.org/netWorth/nw1/assetContainer>
   a ldp:Container;
   dcterms:title "The assets of JohnZSmith";
   ldp:membershipSubject <http://example.org/netWorth/nw1>;
   ldp:membershipPredicate o:asset.

<http://example.org/netWorth/nw1/assetContainer?p=2>
   a ldp:Page;
   ldp:pageOf <http://example.org/netWorth/nw1/assetContainer>;
   ldp:nextPage rdf:nil.

<http://example.org/netWorth/nw1>
   a o:NetWorth;
   o:asset 
      <http://example.org/netWorth/nw1/assetContainer/a5>.

<http://example.org/netWorth/nw1/assetContainer/a5>
   a o:Stock;
   dcterms:title "Big Co.";
   o:value 200.02.

In this example, there is only one member in the container in the final page. To indicate this is the last page, a value of rdf:nil is used for the ldp:nextPage predicate of the page resource.

LDPC guarantees that any and all the triples about the members will be on the same page as the membership triple for the member.

5.1.4 Ordering
This section is non-normative

There are many cases where an ordering of the members of the container is important. LDPC does not provide any particular support for server ordering of members in containers, because any client can order the members in any way it chooses based on the value of any available property of the members. In the example below, the value of the o:value predicate is present for each member, so the client can easily order the members according to the value of that property. In this way, LDPC avoids the use of RDF constructs like Seq and List for expressing order.

Order only becomes important for LDPC servers when containers are paginated. If the server does not respect ordering when constructing pages, the client is forced to retrieve all pages before sorting the members, which would defeat the purpose of pagination. In cases where ordering is important, a LDPC server exposes all the members on a page with a higher sort order than all members on the previous page and lower sort order than all the members on the next page. The LDPC specification provides a predicate - ldp:containerSortPredicates - that the server may use to communicate to the client which predicates were used for page ordering. Multiple predicate values may have been used for sorting, so the value of this predicate is an ordered list.

Here is an example container described previously, with representation for ordering of the assets:

Example 8
# The following is the ordered representation of
#   http://example.org/netWorth/nw1/assetContainer
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix o: <http://example.org/ontology/>.

<http://example.org/netWorth/nw1/assetContainer>
   a ldp:Container;
   dcterms:title "The assets of JohnZSmith";
   ldp:membershipSubject <http://example.org/netWorth/nw1>;
   ldp:membershipPredicate o:asset.

<http://example.org/netWorth/nw1/assetContainer?firstPage>
   a ldp:Page;
   ldp:pageOf <http://example.org/netWorth/nw1/assetContainer>;
   ldp:containerSortPredicates (o:value).

<http://example.org/netWorth/nw1>
   a o:NetWorth;
   o:asset
      <http://example.org/netWorth/nw1/assetContainer/a1>,
      <http://example.org/netWorth/nw1/assetContainer/a3>,
      <http://example.org/netWorth/nw1/assetContainer/a2>.

<http://example.org/netWorth/nw1/assetContainer/a1>
   a o:Stock;
   o:value 100.00.
<http://example.org/netWorth/nw1/assetContainer/a2>
   a o:Cash;
   o:value 50.00.
<http://example.org/netWorth/nw1/assetContainer/a3>
   a o:RealEstateHolding;
   o:value 300000.

As you can see by the addition of the ldp:containerSortPredicates predicate, the o:value predicate is used to define the ordering of the results. It is up to the domain model and server to determine the appropriate predicate to indicate the resource’s order within a page, and up to the client receiving this representation to use that order in whatever way is appropriate, for example to sort the data prior to presentation on a user interface.

5.2 General

This section is non-normative.

5.2.1 LDPC servers must also be conformant LDPR servers. A Linked Data Platform Container is a resource that is a Linked Data Platform Resource.
5.2.2 The same resource may be a member of multiple LDPCs. This happens commonly if one container is a view onto a larger container.
5.2.3 The representation of a LDPC includes information about which resources are its members. The set of members of a container is a set of triples in its representation (and state) called the membership triples. The membership triples of a container all have the same subject and predicate – the objects of the membership triples define the members of the container. The subject of the membership triples is called the membership subject and the predicate is called the membership predicate. In the simplest cases, the membership subject will be the LDPC resource itself, but it does not have to be. The membership predicate is also variable and will often be a predicate from the server application vocabulary. If there is no obvious predicate from the server application vocabulary to use, LDPC servers should use the rdfs:member predicate.
container affordances
5.2.4 A LDPC must contain one triple for the ldp:membershipSubject predicate that indicates the subject of the membership triples when container subject is not the LDPC itself.
5.2.5 A LDPC must contain one triple for the ldp:membershipPredicate predicate that indicates the predicate of the membership triple when the container predicate is not rdfs:member.
5.2.6 The representation of a LDPC may include an arbitrary number of additional triples whose subjects are the members of the container, or that are from the representations of the members (if they have RDF representations). This allows a LDPC server to provide clients with information about the members without the client having to do a GET on each member individually. See section 5.1.1 Container Member Information for additional details.
Include clarifications about LDPC representations that include member triples
5.2.7 The representation of a LDPC must have rdf:type of ldp:Container, but it may have additional rdf:types.
5.2.8 LDPCs should not use RDF container types rdf:Bag, rdf:Seq and rdf:List.
Do LDPC versions get managed in a systematic, discoverable way?

5.3 HTTP GET

5.3.1 The representation of a LDPC must contain a set of triples with a consistent subject and predicate whose objects indicate members of the container. The subject of the triples may be the container itself or may be another resource (as in the example above). See also 5.2.3.
5.3.2 LDPC servers should support requests for information about a known LDPC without retrieving a full representation including all of its members, by the existence of the token "non-member-properties" on the query component of the LDPC URL. For example, if there is a LDPC URL <containerURL>, the URL to request the non-membership properties would be <containerURL>?non-member-properties. See section 5.1.2 Retrieving Non-member Properties for additional details. A LDPC server that does not support a request to retrieve non-member resource properties via a Request-URI of “<containerURL>?non-member-properties”, must return a HTTP status code 404 (Not Found).
5.3.3 A LDPC server that does not support a request to retrieve the first page resource representation via a known LDPC as “<containerURL>”, the Request-URI of “<containerURL>?firstPage”, must return a HTTP status code 404 (Not Found).
5.3.4 LDPC servers should support requests for splitting large LDPCs into pages indicated by a client supplying the token “firstPage” on the query component of the LDPC URL. For example, if there is a LDPC URL <containerURL>, the URL to request the first page would be <containerURL>?firstPage. The representation for any page, including the first, will include the URL for the next page. See section 5.1.3 titled “Paging” for additional details.
5.3.5 LDPC servers may split the response representation of a LDPC regardless of what the client requested (such as when a client omits a “firstPage” query component of a request URL). This is also known as server-initiated paging. See section 5.1.3 Paging for additional details.
5.3.5.1 LDPC servers that initiate paging should respond to requests for a LDPC by redirecting the client to the page resource – using a 303 “See Other” redirect to the actual URL for the page resource.
5.3.6 LDPC servers that support paging must include in the page representation a representation for the LDPC, such that:
5.3.6.1 The page resource representation should have one triple to indicate its type, whose subject is the URL of the page, whose predicate is rdf:type and object is ldp:Page; it also should have 1 triple to indicate the container it is paging, whose subject is the URL of the page, predicate is ldp:pageOf, and object is the URL of the LDPC.
5.3.6.2 The page resource representation must have one triple with the subject of the page, predicate of ldp:nextPage and object being the URL for the subsequent page.
5.3.6.3 The last page resource representation must have one triple with the subject of the last page, predicate of ldp:nextPage and object being rdf:nil.
container membership and robust pagination
5.3.7 LDPC servers may represent the members of a paged LDPC in a sequential order. The order must be specified using the ldp:containerSortPredicates predicate whose subject is that of the page and object is a list of LDPC ordinal predicates. The default ordering is ascending. The only ordinal predicate literal data types supported are those as defined by SPARQL SELECT’s ORDER BY clause [SPARQL-QUERY].
Include clarifications about ordering in LDPC representations
5.3.7.1 The object of ldp:containerSortPredicates’, the predicate used to indicate ordering, must not change between subsequent pages. If it does, ordering among members of a container across pages is undefined. See section 5.1.4 Ordering for additional details.

The Linked Data Platform does not define how clients discover LDPCs.

5.4 HTTP POST

5.4.1 LDPC clients should create resources by submitting a representation as the entity body of the HTTP POST to a known LDPC. LDPC servers must respond with status code 201 (Created) and the Location header set to the new resource’s URL.
5.4.2 After a successful HTTP POST request to a LDPC, the new resource must appear as a member of the LDPC until the new resource is deleted or removed by other methods. A LDPC may also contain resources that were added through other means - for example through the user interface of the site that implements the LDPC.
5.4.3 LDPC servers may accept an HTTP POST of non-RDF representations for creation of any kind of resource, for example binary resources.
5.4.4 For servers that support create, LDPC servers must create a LDPR from a RDF representation in the request entity body.
5.4.5 LDPC servers should not include the representation of the created resource in the entity body of a 201 (Created) response. In other words, clients should not expect any representation in the response entity body on a 201 (Created) response.
5.4.6 For LDPCs, servers must accept a request entity body with a content type of text/turtle [TURTLE].
5.4.7 For LDPCs, LDPR servers should accept a request with an entity body content type of application/rdf+xml [RDF-SYNTAX].
5.4.8 For RDF representations, LDPC servers must interpret the null relative URI for the subject of triples in the LDPR representation in the request entity body as referring to the entity in the request body. Commonly, that entity is the model for the “to be created” LDPR, so triples whose subject is the null relative URI will usually result in triples in the created resource whose subject is the created resource.
Identifying and naming POSTed resources
5.4.9 LDPC servers should assign the subject URI for the resource to be created using server application specific rules.
5.4.10 LDPC servers should allow clients to create new resources without requiring detailed knowledge of application-specific constraints. Some LDPC servers put restrictions on representations – for example, the range of rdf:type, datatypes of predicates and number of occurrences of predicates in triples - but server enforcement of detailed, domain-specific constraints will greatly restrict the types of clients that can create resources and therefore discouraged.

5.5 HTTP PUT

5.5.1 LDPC servers should not allow HTTP PUT to update a LDPC’s members and if the server receives such a request, it should respond with a 409 (Conflict) status code.
5.5.2 LDPC servers may allow updating LDPC non-membership properties using HTTP PUT on <containerURL>?non-member-properties, which may exclude server managed properties such as ldp:membershipSubject and ldp:membershipPredicate.

5.6 HTTP DELETE

5.6.1 If a LDPC server supports deletion of the LDPC, the server may also delete the resources that are referenced as its contents.
5.6.2 When a resource that is contained in a LDPC (for example referenced by a membership triple) is deleted, the server must also remove it from the LDPC that was used to create it and should remove it from any other containers that reference it that the server manages and persists.

5.7 HTTP HEAD

There are no additional requirements on HTTP HEAD.

5.8 HTTP PATCH

5.8.1 LDPC servers are recommended to support HTTP PATCH as the preferred method for updating LDPC non-membership properties.
What operations are permittered on containers and how do they get invoked?

A. Acknowledgements

This section is non-normative.

The following people have been instrumental in providing thoughts, feedback, reviews, criticism and input in the creation of this specification:

B. Change History

This section is non-normative.

C. Editor Todos and Notes

This section is non-normative.

Other than LDP open actions and issues, included here are transient tasks and notes editors use. They have not meaning in final product of a published working draft and will be removed prior to publishing.

Add a section explaining how LDBP is related to Graph Store Protocol

D. References

D.1 Normative references

[DC-RDF]
M. Nilsson; et al. Expressing Dublin Core metadata using the Resource Description Framework (RDF). 14 January 2008. DCMI Recommendation. URL: http://dublincore.org/documents/2008/01/14/dc-rdf/
[DC-TERMS]
Dublin Core Metadata Initiative. Dublin Core Metadata Initiative Terms, version 1.1. 11 October 2010. DCMI Recommendation. URL: http://dublincore.org/documents/2010/10/11/dcmi-terms/.
[HTML401]
David Raggett; Ian Jacobs; Arnaud Le Hors. HTML 4.01 Specification. 24 December 1999. W3C Recommendation. URL: http://www.w3.org/TR/1999/REC-html401-19991224
[HTTP11]
R. Fielding; et al. Hypertext Transfer Protocol - HTTP/1.1. June 1999. Internet RFC 2616. URL: http://www.ietf.org/rfc/rfc2616.txt
[RDF-PRIMER]
Frank Manola; Eric Miller. RDF Primer. 10 February 2004. W3C Recommendation. URL: http://www.w3.org/TR/2004/REC-rdf-primer-20040210/
[RDF-SCHEMA]
Dan Brickley; Ramanathan V. Guha. RDF Vocabulary Description Language 1.0: RDF Schema. 10 February 2004. W3C Recommendation. URL: http://www.w3.org/TR/2004/REC-rdf-schema-20040210
[RDF-SYNTAX]
Ora Lassila; Ralph R. Swick. Resource Description Framework (RDF) Model and Syntax Specification. 22 February 1999. W3C Recommendation. URL: http://www.w3.org/TR/1999/REC-rdf-syntax-19990222
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Internet RFC 2119. URL: http://www.ietf.org/rfc/rfc2119.txt
[RFC4627]
D. Crockford. The application/json Media Type for JavaScript Object Notation (JSON) July 2006. Internet RFC 4627. URL: http://www.ietf.org/rfc/rfc4627.txt
[RFC5789]
L Dusseault, J. Snell. PATCH Method for HTTP. March 2010. Internet Proposed Standard RFC 5789. URL: http://tools.ietf.org/html/rfc5789
[SPARQL-QUERY]
E. Prud'hommeaux, A. Seaborne. SPARQL Query Language for RDF. W3C Recommendation. 15 January 2008. URL: http://www.w3.org/TR/2008/REC-rdf-sparql-query-20080115/
[SPARQL-UPDATE]
S. Schenk, P. Gearon. SPARQL 1.1 Update.W3C Working Draft. 26 January 2010. URL: http://www.w3.org/TR/2010/WD-sparql11-update-20100126/
[TURTLE]
David Beckett, Tim Berners-Lee. Turtle: Terse RDF Triple Language. January 2008. W3C Team Submission. URL: http://www.w3.org/TeamSubmission/turtle/
[XMLSCHEMA11-2]
Henry S. Thompson; et al. W3C XML Schema Definition Language (XSD) 1.1 Part 2: Datatypes. 5 April 2012. W3C Recommendation URL: http://www.w3.org/TR/2012/REC-xmlschema11-2-20120405/

D.2 Informative references

[LINKED-DATA]
Tim Berners-Lee. Linked Data. 18 June 2009. Design Issue. (Work in progress.) URL: http://www.w3.org/DesignIssues/LinkedData.html
[WEBARCH]
Norman Walsh; Ian Jacobs. Architecture of the World Wide Web, Volume One. 15 December 2004. W3C Recommendation. URL: http://www.w3.org/TR/2004/REC-webarch-20041215/