Copyright © 2014W3C® (MIT,ERCIM,Keio,Beihang), All Rights Reserved.W3Cliability,trademark anddocument use rules apply.
This document provides best practicesand guidelines for implementing Linked Data Platform [LDP] serversand clients.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of currentW3C publications and the latest revision of this technical report can be found in theW3C technical reports index at http://www.w3.org/TR/.
This document was published by theLinked Data Platform Working Group as a Working Group Note. If you wish to make comments regarding this document, please send them topublic-ldp@w3.org (subscribe,archives). All comments are welcome.
Publication as a Working Group Note does not imply endorsement by theW3C 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 the5 February 2004W3C Patent Policy.W3C maintains apublic 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 containsEssential Claim(s) must disclose the information in accordance withsection 6 of theW3C Patent Policy.
While writing the Linked Data Platform Specification, theauthors and contributors felt compelled to share common conventionsand valuable lessons-learned. Yet, at the same time, they did notwish to impose or imply unnecessary restrictions, or to make theformal specification unnecessarily verbose. This document, alongwith the LDP Primer [LDP-PRIMER], was therefore developed toprovide additional context. Drawing upon the professionalexperiences of its authors and contributors, research into the richhistory of related technologies, and continuous feedback from thecommunity at large, it aims to help system implementers avoid commonpitfalls, improve quality, and achieve greater interoperability withother Linked Data systems.
For the purposes of this document, it is useful tomake a minor, yet important distinction between the term 'bestpractice' and the term 'guideline'. We define and differentiate the terms as follows:
Please see the Terminology section in Linked Data Platform 1.0[LDP] as well as the Linked Data Glossary [LD-GLOSSARY] fordefinitions to a variety of terms used in this document and relatedto the Linked Data sphere of knowledge.
Implementers should have at least a general familiarity with theinformative references cited inthis document - especially the following:
URIs are used to uniquely identify resources and URLs are usedto locate resources on the Web. That is to say that a URL isexpected to resolve to an actual resource, which can be retrievedfrom the host. A URI, on the other hand, may also be a URL, but itdoes not have to be; it may refer to something that has noretrievable representation.
One of the fundamental ideas behind Linked Data is that thethings referred to by HTTP URIs can actually be looked up("dereferenced"). This important principle was originallyoutlined by Tim Berners-Lee as rule #2 of "the four rules"for linking data [LD-DI]. It is therefore ideal that predicateURIs identify resources with representations that are retrievable. LDPservers should at least provide [RDF-SCHEMA] representations ofthese predicates where possible.
Of course, it is also a common practice to reuse propertiesfrom open vocabularies that are publicly available. In this case,implementers have no control over the result when attempting todereference the URI. For this reason, publishers who wish to maketheir vocabularies useful for linking data should strive to providea retrievable representation of the properties their vocabulariesdefine. Consequently, implementers are also expected to use thispractice as a benchmark for which to judge the efficacy of avocabulary's use for linking data.
It is often very useful to know the type (class) of an LDPR, thoughit is not essential to work with the interaction capabilities thatLDP offers. Still, to make data more useful in the broadest context,type should be explicitly defined using therdf:type
predicate defined by [RDF-SCHEMA].
This provides a way for clients to easily determine the type(s)of a resource without having to perform additional processing ormake additional HTTP requests. For example, clients that cannotinfer the type because they do not support inferencing can benefitfrom this explicit declaration.
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.@prefix contact: <http://www.w3.org/2000/10/swap/pim/contact#>.<http://www.w3.org/People/EM/contact#me> a contact:Person; contact:fullName "Eric Miller"; contact:mailbox <mailto:em@w3.org>; contact:personalTitle "Dr.".
The token 'a' in the predicate position of a Turtle triple represents the IRI http://www.w3.org/1999/02/22-rdf-syntax-ns#type. In the example above, therefore,a contact:Person
is the same asrdf:type contact:Person
or the fully-qualified form,<http://www.w3.org/1999/02/22-rdf-syntax-ns#type> contact:Person
.
Relative URIs are useful to the Linked Data Platform in muchthe same ways that relative URLs [RFC3986] have been useful totraditional web systems. Since the things referred to by Linked DataURIs should provide a retrievable representation [LD-DI], LinkedData URIs are usually also URLs; they locate rather than justidentify. As such, the utilitarian value of relative URLs stillapplies; especially since the LDP Container model promoteshierarchical representations.
Implementers should therefore align the function of relativeURIs in LDP with those of traditional relative URLs where possibleand appropriate. Aside from giving developers the comfort andconvenience of familiarity, they provide many of the sameadvantages.
In many cases, this can aid development by making code andRDF easier for humans to read. It can also reduce the size ofpayloads, which in turn, can reduce network traffic and stress onservers, while improving response times for end-users.
@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 a ldp:Container, ldp:BasicContainer; dcterms:title "A very simple container"; ldp:contains <http://example.org/container1/member1>, <http://example.org/container1/member2>, <http://example.org/container1/member3>.
@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#>.<> a a ldp:Container, ldp:BasicContainer; dcterms:title "A very simple container"; ldp:contains <member1>, <member2>, <member3> .
/people/
for example, may create the resource/people/1
. LDP Containers are such collections whose URIs can benefit fromthe same model, which in some implementations, may actually becrucial.The semantics of dot-segments (eg.../
) within relative URIs may be implied by other specifications and by common historical use, but in the case of LDP, additional consideration is required.
The LDP specification states that...
LDP serversMUST assign the default base-URI for [RFC3987] relative-URI resolution to be the HTTP Request-URI when the resource already exists, and to the URI of the created resource when the request results in the creation of a new resource.It follows from this definition that use of
../
and other non-null relative URI constructs during POST can cause the posted content to be referring to resources in a manner the client might not be able to predict. Dot-segments should therefore be avoided unless the client knows specifically what can be expected of the given implementation and/or deployment.Hierarchical URIs are good for containers because they enablethe use of relative URIs. They also promote easy interaction withresources that are modeled to represent parent-child relationshipswhere the child logically belongs to the parent.
One example of such a model can be found in the case of theoslc_cm:attachment
container from the vocabularies defined by theOpen Service for LifecycleManagement (OSLC) community. The OSLC defines specifications andvocabularies that are well-aligned to LDP. A resource in an OSLCcompliant change management system such as an issue or bug trackermay have attachments represented by theoslc_cm:attachment
container. The URI for such a container might be represented asfollows:
http://example.org/bugs/2314/attachments/
From this URI, the URI of the parent resource which holds theattachments is easily discerned. The base container for othersibling resources can be discerned by moving up the hierarchy, whichis implied by the URI. Meta-data or binary content might be fetchedfurther down the hierarchy by using a URI such as the following:
http://example.org/bugs/2314/attachments/1
In addition to making the use of relative URIs possible,hierarchical URIs make interacting with resources easier for users becausethey represent the actual structure of the underlying graph.Software agents (code acting on behalf of users [WEBARCH]) must be carefulbefore exploiting the structure of URIs, considering historical problemswhen doing so ([WEBARCH], [metaDataInURI]).
When representing container membership with hierarchical URLs,including the trailing slash in a container's URI makes it easier to use relative URIs.Take the following container URI for example:
http://example.org/container1
It is more advantageous to use the following instead:
http://example.org/container1/
To illustrate the advantage, let's start with the followingcontainer using absolute URIs:
@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 a ldp:Container, ldp:BasicContainer; dcterms:title "A very simple container"; ldp:contains <http://example.org/container1/member1>, <http://example.org/container1/member2>, <http://example.org/container1/member3>.
Suppose now that we wish to reflect the same resource usingrelative URIs. If the URI of the container includes the trailingslash, we end up with a very elegant representation, as shown below.
@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#>.<> a a ldp:Container, ldp:BasicContainer; dcterms:title "A very simple container"; ldp:contains <member1>, <member2>, <member3> .
But suppose that we omit the trailing slash, issued an HTTPGET, and the container returned the representation shown above. Thiscould produce a graph that is equivalent to the following:
@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 a ldp:Container, ldp:BasicContainer; dcterms:title "A very simple container"; ldp:contains <http://example.org/member1>, <http://example.org/member2>, <http://example.org/member3>.
That is not what was intended; the member URLs lack thecontainer
path segment.The returned document wouldhave to be more verbose in order to be correct:
@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#>.<> a a ldp:Container, ldp:BasicContainer; dcterms:title "A very simple container"; ldp:contains <container1/member1>, <container1/member2>, <container1/member3> .
So, clearly, the better solution is to ensure that containerURIs end with a trailing slash.
Resource URIs are permitted to end with a fragment; the fragmentcomponent is delimited from the rest of the URI because it isintroduced by a hash mark (#
).For this reason, URIs with non-empty fragments are often called hash URIs;a hash URI identifies a subordinate or related resource [RFC3986].
Take the URI,http://www.example.org/products#item10245
, for example. The non-fragment portion of the URI is the part preceding the hash mark,http://www.example.org/products
, and the fragment identifier is the part that follows,item10245
.
When expressing Linked Data Platform Resources in RDF,fragments are useful because they can be expressed as relative URIson the document describing them. This is particularly handy fordescribing multiple LDPRs whose representations are contained withina single document.
First, it provides the convenience and efficiency of brevity.Suppose, for example, the resources foo, bar, and baz arecontained in the same document. Since serving all of thedescriptions in a single document is acceptable, we can mintrelative URIs within the document using the fragment identifier (<#foo>
,<#bar>
and<#baz>
). [LDP] ensures that the default base URI is the documentURI (http://www.example.org/products
), so the absolute URI for each is the base URI, plus the hash mark,plus the fragment identifier.
Second, it can help avoid certain complexities inherent withother approaches. Achieving the same result using three independentdereferenceable URIs could be more involved because multipledocuments would have to be published, perhaps also including thesetup of 303 redirects.
See also:
Axioms ofWeb Architecture, URI References: Fragment Identifiers on URIs
http://www.w3.org/DesignIssues/Fragment.html
DereferencingHTTP URIs
http://www.w3.org/2001/tag/doc/httpRange-14/2007-05-31/HttpRange-14
LDPR representations should use only the following standarddatatypes. RDF does not by itself define datatypes to be used forliteral property values, therefore a set of standard datatypes basedon [XMLSCHEMA11-2] and [RDF-PRIMER11] should be used:
URI | Description |
---|---|
http://www.w3.org/2001/XMLSchema#boolean | Boolean type as specified by XSD Boolean |
http://www.w3.org/2001/XMLSchema#date | Date type as specified by XSD date |
http://www.w3.org/2001/XMLSchema#dateTime | Date and Time type as specified by XSD dateTime |
http://www.w3.org/2001/XMLSchema#decimal | Decimal number type as specified by XSD Decimal |
http://www.w3.org/2001/XMLSchema#double | Double floating-point number type as specified by XSDDouble |
http://www.w3.org/2001/XMLSchema#float | Floating-point number type as specified by XSD Float |
http://www.w3.org/2001/XMLSchema#hexBinary | Arbitrary hex-encoded binary data as specified by XSD hexBinary |
http://www.w3.org/2001/XMLSchema#integer | Integer number type as specified by XSD Integer |
http://www.w3.org/2001/XMLSchema#string | String type as specified by XSD String |
http://www.w3.org/2001/XMLSchema#base64Binary | Binary type as specified by XSD Base64Binary |
http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral | Literal XML value as specified by RDF |
This section summarizes some well-known RDF vocabularies that shouldbe used in Linked Data Platform Resources wherever a resource needsto use a predicate whose meaning matches one of these. For example,if a resource has a description, and the application semantics ofthat description is compatible withdcterms:description
, thendcterms:description
should be used. If needed, additional application-specificpredicates may be used. A specification for a domain may require oneor more of these properties for a particular resource type. TheRange column in the tables below identifies the definedrdfs:range
for the properties.
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 richtext in XHTML format. should include only content that is validand suitable inside an XHTML element. |
dcterms:identifier | rdfs:Literal | |
dcterms:modified | xsd:dateTime | |
dcterms:relation | rdfs:Resource | The HTTP URI of a related resource. This is the predicateto use when you don't know what else to use. If you know morespecifically what sort of relationship it is, use a more specificpredicate. |
dcterms:subject | rdfs:Resource | |
dcterms:title | rdf:XMLLiteral | A name given to the resource. Represented as rich text inXHTML format. should include only content that is valid inside anXHTML element. |
The predicatedcterms:type
should not be used, instead userdf:type
. [DC-RDF].
From RDF URI:http://www.w3.org/1999/02/22-rdf-syntax-ns#
Property | Range/DataType | Comment |
---|---|---|
rdf:type | rdfs:Class | The type or types of the resource |
From RDF Schema URI:http://www.w3.org/2000/01/rdf-schema#
Property | Range/DataType | Comment |
---|---|---|
rdfs:member | rdfs:Resource | |
rdfs:label | rdfs:Literal | Only use this in vocabulary documents, to define the nameof the vocabulary term. |
Quality factors allow the user or user agent to indicate therelative degree of preference for a media-range, using the qvaluescale from 0 to 1. The default value is q=1. Take the following forexample:
Accept: text/turtle; q=0.5, application/json
This should be interpreted as "I prefer application/json, butsend me text/turtle if it is the best available after a 50%mark-down in quality."
Improper handling of qvalues is a common problem inimplementations of content negotiation.
Refer to Section 14, Header Field Definitions, in the[HTTP11] specification to understand the proper use and evaluationof qvalues for both client and server implementations.
Clients can access an LDPR using multiple URLs. An LDP servershould respond to each of those requests using a single consistentURL, a primary URL, for the LDPR. This primary URL may be foundin the response's Location and/or Content-Location headers, andpotentially also in the representation of the LDPR. A common case isURLs that vary by protocol, one HTTP and one HTTPS, but areotherwise identical. In most cases those two URLs refer to the sameresource, and the server should respond to requests on either URLwith a single (primary) URL.
Clients should use the primary URL as an LDPR's identity;for example, when determining if two URLs refer to the same resourceclients should compare the primary URLs, not the URLs used toaccess the resources. Note that this usagedoes imply that theclient has sufficient reason to trust the headers and/or contentby which the primary URL is communicated to the client, which is beyond what HTTP alone can guarantee [RFC7231].
LDPRs can use one RDF triple to represent a link(relationship) to another resource. Having the source resource’s URIas the subject and the target resource’s URI as the object of thetriple is enough. Contrary to a misconception that readers withcertain backgrounds may assume, the creation of an"intermediate link" resource is not required to expressthe relationship.
LDP servers should enable simple creation and modification ofLDPRs.
It may be common for LDP servers to put restrictions onrepresentations – for example, the range of rdf:type predicates,datatypes of the objects of predicates, and the number ofoccurrences of predicates in an LDPR, but servers should minimizesuch restrictions.
For some server applications, excessive constraints onmodification of resources may be required. However, enforcement ofmore complex constraints will greatly restrict the set of clientsthat can modify resources. For interoperability with a wider rangeof clients, implementers are therefore encouraged to minimizeserver-specific constraints.
It is important to remember that a Linked Data PlatformContainer (LDPC) is also a Linked Data Platform RDF Source (LDP-RS) andthough it might exist as a membership controller, it may also represent additional data that is valuable to the agents that accessit.
Following are some useful resources for finding and leveragingpre-existing, common, and well-established vocabularies.
Many thanks to Robin Berjon and all contributors to theReSpec tool, which makes writing these kinds of documents much easier.
To the following individuals who, in addition to the editors, have contributed either directly or indirectly to the ongoing improvement of this document: