Warning:
This wiki has been archived and is now read-only.
Primer
This wiki is obsolete now. The latest version of the LDP Primer can be found here.
This page collects content for a future Note on LDP Primer to be produced by the Linked Data Platform WG.
This primer provides an introduction to Linked Data Platform (LDP), including the basic concepts of LDP including Linked Data Platform Resources (LDPRs), Linked Data Platform Containers (LDPCs), their affordances, and a running example showing how an LDP client can interact with an LDP server in the context of read-write Linked Data application. The examples show how to use LDP protocol for accessing, updating, creating and deleting resources from servers that expose their resources as Linked Data.
Contents
1 Introduction
Linked Data is a universal approach for handling data which fundamentally includes the notion linking between data items. Much like the Web is giant network of interlinked documents for a human reader, the graph of Linked Data in the Web is a data layer on top of which applications are delivered, information is modified, processed, visualised and shared.
There will be several categories of systems implementing the LDP specification. Two main categories of the LDP servers include:
- Generic / vanilla LDP servers - RDF storage systems that allow interacting with their resources by means of the LDP specification. These servers do not impose any restriction on LDPRs.
- Application specific LDP severs - Systems exposing their data using the LDP specification. These systems impose restrictions on LDPRs since they have an underlying business logic and data model.
2 Organization of this Document
2.1 2.1 Conventions Used in This Document
We provide examples representations 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#>. @prefix bt: <http://example.org/vocab/bugtracker#>.
3 Examples
This section provides a set of examples to show the Linked Data Platform interactions. Note, this is a primer and should not be considered as a canonical example of ideal LDP modelling.
The examples in this section will revolve around a very simple Bug Tracker application. Bug Tracker application records the bugs of several products allowing reporting, updating and deleting bugs and products. We can re-use simple domain vocabulary, e.g. has_bug or related, to express our data. LDP provides the additional interaction capability in the protocol to perform dynamic evolution of knowledge representation.
Path | Method | Description |
---|---|---|
Orange | 10 | 7.00 |
Bread | 4 | 3.00 |
Butter | 1 | 5.00 |
3.1 Simple Scenarios
3.1.1 Lookup a ProductError creating thumbnail: Unable to save thumbnail to destination
|
The client request a GET with the URI of a known Product resource. GET /app/product1 HTTP/1.1 Host: example.org Accept: text/turtle If the resource is available, the server responds with the representation of the resource. HTTP/1.1 200 OK Content-Type: text/turtle ETag: W/"123456789" </app/product1> a bt:Product, ldp:Container; ldp:membershipPredicate bt:hasbug ; dcterms:title "Product 1" ; bt:hasbug </app/product1/bug3> ; bt:hasbug </app/product1/bug4> . |
3.1.2 Lookup a BugError creating thumbnail: Unable to save thumbnail to destination
|
Based on links in the representation of the Product, the client uses GET to navigate to a known Bug resource. GET /app/product1/bug3 HTTP/1.1 Host: example.org Accept: text/turtle The server responds with the representation of the resource. HTTP/1.1 200 OK Content-Type: text/turtle ETag: W/"123456789" </app/product1/bug3> a bt:Bug; dcterms:title "Product A crashes when shutting down."; dcterms:creator </app/users/johndoe>; dcterms:created "2013-05-05T10:00"^^xsd:dateTime bt:isInState "New" . |
3.1.3 Update a BugError creating thumbnail: Unable to save thumbnail to destination
|
PUT /app/product1/bug3 HTTP/1.1 Host: example.org Content-Type: text/turtle If-Match: W/"123456789" </app/product1/bug3> a bt:Bug; dcterms:title "Product 1 crashes when shutting down."; dcterms:creator </app/users/johndoe>; dcterms:created "2013-05-05T10:00"^^xsd:dateTime; bt:isInState "InProgress"; bt:relatedBug </app/product1/bug4> . If the update is successful, the server will respond with a success status and a new etag. HTTP/1.1 204 No Content ETag: W/"123456790"
|
3.1.4 Create a new BugError creating thumbnail: Unable to save thumbnail to destination
|
Continuing from the previous example, we can report a Bug against 'product1' by creating a Bug LDPR under the 'Product' LDPC. The client POSTs a representation of a Bug to the Bug Tracker LDPC. POST /app/product1 HTTP/1.1 Host: example.org Content-Type: text/turtle <> a bt:Bug; dcterms:title "Product A crashes when shutting down."; dcterms:creator </app/users/johndoe> . If the create is successful, the server responds with location of the newly created resource. HTTP/1.1 201 Created Location: http://example.org/app/BugTracker/ProductA/Bug1 Content-Length: 0 If the creation fails, the server will respond with an appropriate status code depending on the error. After the resource is creation, the Product A LDPC will have the following representation. <http://example.org/app/BugTracker/ProductA> a ldp:Container, bt:Product; dcterms:title "A container that tracks bugs of Product A" ; bt:hasbug </app/product1/bug3> ; bt:hasbug </app/product1/bug4> ; bt:hasbug </app/product1/bug67> . And the created Bug resource will have the following representation. Note that server has added a server managed property, creation date (dcterms:created), and a default value for the state (bt:isInState) to the Bug in addition to what was being POSTed. </app/product1/bug67> a bt:Bug; dcterms:title "Product A crashes when shutting down."; dcterms:creator </app/users/johndoe>; dcterms:created "2013-05-05T10:00"^^xsd:dateTime; bt:isInState "New" . |
3.2 Basic scenarios
3.2.1 Creating a Project
If the LDP server may allow creating LDPC by posting a representation of the container to an existing container. So we will add a new Product
The mechanism for creating the first ever container of a system is not defined in the specification and it is assumed that servers will make available one or more containers as the starting point for interacting with the server. In this example, we assume that 'Bug Tracker' container is already available and it has the following representation.
</app> a ldp:Container, bt:BugTracker ; ldp:membershipPredicate bt:tracksProject .
Steps
The client POSTs a representation of the 'Project A' to the Bug Tracker LDPC. As the URI of the 'Project A' is not known until it's created, clients can include a null relative URI in the representation and the LDP servers interpret the null relative URI for the subject of triples in the request entity body as referring to the entity in the request body.
POST /app/BugTracker HTTP/1.1 Host: example.org Content-Type: text/turtle Slug: ProductA <> a ldp:Container, bt:Product; dcterms:title "A container that tracks bugs of Product A" .
If the create is successful, the server responds with location of the newly created container.
HTTP/1.1 201 Created Location: http://example.org/app/BugTracker/ProductA Content-Length: 0
If the creation fails, the server will respond with an appropriate status code depending on the error.
After creation of this new container, 'Product A', the representation of the 'Tracker' container will be
<http://example.org/app/BugTracker> a ldp:Container; rdfs:member <http://example.org/app/BugTracker/ProductA> .
and the 'Product A' will have the following representation.
<http://example.org/app/BugTracker/ProductA> a ldp:Container, bt:Product; dcterms:title "A container that tracks bugs of Product A" .
3.2.2 Updating a Project
LDP servers may allow updating certain resources. For example, in the Bug Tracker application bugs can be updated to change their state and/or add information about related bugs. Depending on which HTTP methods the server supports, different alternatives are available.
- PATCH, if supported by the server, scales best in that it sends only the changes needed. The client typically creates the patch document describing the changes to make to the resource’s state, and then performs a PATCH request with the patch document as the request payload to update the resource.
- PUT exists as a fallback. The client performs a GET request to obtain the resource’s Etag value and representation, updates the resource’s representation, and performs a conditional PUT request using that Etag value to update the resource.
Steps
First, get the resource that has to be updated.
GET /app/BugTracker/ProductA/Bug1 HTTP/1.1 Host: example.org Accept: text/turtle
HTTP/1.1 200 OK Content-Type: text/turtle ETag: W/"123456789" <http://example.org/app/BugTracker/ProductA/Bug1> a bt:Bug; dcterms:title "Product A crashes when shutting down."; dcterms:creator <http://example.org/users/johndoe>; dcterms:created "2013-05-05T10:00"^^xsd:dateTime bt:isInState "New" .
An alternative way of retrieving the entity tag would be to use the HEAD operation in the cases whether the current representation of the resource is not necessary.
HEAD /app/BugTracker/ProductA/Bug1 HTTP/1.1 Host: example.org Accept: text/turtle
HTTP/1.1 204 No Content Allow: GET, PUT, POST, HEAD, PATCH, DELETE ETag: W/"123456789"
After the modifications are done in the resource, the updated representation can be PUT to the resource URI. The etag from the previous retrieval has to be send along with the PUT request.
PUT /app/BugTracker/ProductA/Bug1 HTTP/1.1 Host: example.org Content-Type: text/turtle If-Match: W/"123456789" <http://example.org/app/BugTracker/ProductA/Bug1> a bt:Bug; dcterms:title "Product A crashes when shutting down."; dcterms:creator <http://example.org/users/johndoe>; dcterms:created "2013-05-05T10:00"^^xsd:dateTime; bt:isInState "InProgress"; bt:relatedBug <http://example.org/app/BugTracker/ProductB/Bug5> .
Alternatively, if a client can use PATCH method to update resource by sending a diff of the changes to the resource if the PATCH is allowed. PATCH is an optional feature in the LDP specification and the clients may use OPTIONS method to determine whether PATCH method is allowed. LDP specification does not mandate any PATCH formats and which PATCH formats are supported by the server has to be communicated out-of-band to the client. In this example, we use changesets as the PATCH format.
PATCH /app/BugTracker/ProductA/Bug1 HTTP/1.1 Host: example.org Content-Type: text/turtle If-Match: W/"123456789" @prefix cs: <http://purl.org/vocab/changeset/schema#>. _:changeSet a cs:ChangeSet ; cs:subjectOfChange <http://example.org/app/BugTracker/ProductA/Bug1> ; cs:createdDate "2012-01-01T00:00:00Z" ; cs:changeReason "Update to in progress and the related bug" ; cs:removal [ a rdf:Statement ; rdf:subject <http://example.org/app/BugTracker/ProductA/Bug1> ; rdf:predicate bt:isInState ; rdf:object "New" . ] ; cs:addition [ a rdf:Statement ; rdf:subject <http://example.org/app/BugTracker/ProductA/Bug1> ; rdf:predicate bt:state ; rdf:object "InProgress" . ] ; cs:addition [ a rdf:Statement ; rdf:subject <http://example.org/app/BugTracker/ProductA/Bug1> ; rdf:predicate bt:relatedBug ; rdf:object <http://example.org/app/BugTracker/ProductB/Bug5> . ] .
If the update is successful, the server will respond with a success status and a new etag.
HTTP/1.1 204 No Content ETag: W/"123456790"
3.2.3 Deleting a Bug
LDP servers may allow deleting resources.
Steps
DELETE /app/BugTracker/ProductA/Bug1 HTTP/1.1 Host: example.org
If the delete is successful, the server will respond with a success status code.
HTTP/1.1 204 No Content ETag: W/"123456790"
3.2.4 Deleting a Project
LDP servers may allow deleting containers.
Steps
DELETE /app/BugTracker/ProductB HTTP/1.1 Host: example.org
If the delete is successful, the server will respond with a success status code.
HTTP/1.1 204 No Content ETag: W/"123456790"
The sever may delete all membership resources (eg. Bug10, Bug11, and Bug12) recursively. But as LDP specification does not mandate this, there is no guarantee that the server will do this recursive delete unless it is advertised out of band.
3.3 Advanced scenarios
3.3.1 Managing binary attachments
ex-1) We have an LDPC which we can use to create binary resources
GET /Bug1/attachments/ HTTP/1.1 Host: example.org Accept: text/turtle HTTP/1.1 200 OK Content-Type: text/turtle ETag: W/"123456789" </Bug1/attachments/> a ldp:Container .
ex-2). We POST the binary resource to the LDPC and it responds with a Location header and a Link header.
POST /Bug1/attachments/ HTTP/1.1 Host: example.org Content-Type: image/png Slug: login-page.png Content-Length: 1254 #### binary data ##### HTTP/1.1 201 Created Location: /Bug1/attachments/login-page.png Link: </Bug1/attachments/attachment1>; rel="meta" Content-Length: 0
ex-3). We can access the created resource using the URI in the location header.
GET /Bug1/attachments/login-page.png Host: example.org Accept: image/png HTTP/1.1 200 OK Content-Type: text/turtle Link: </Bug1/attachments/attachment1>; rel="meta" ETag: W/"123456789" #### binary data #####
ex-4). We can access the metadata about the resource using the URI in the Link header.
GET /Bug1/attachments/attachment1 Host: example.org Accept: text/turtle HTTP/1.1 200 OK Content-Type: text/turtle ETag: W/"123456789" </Bug1/attachments/login-page.png> wdrs:describedby </Bug1/attachments/attachment1> ; </Bug1/attachments/login-page.png> ; dct:created "2013-05-27T17:05Z"^^xsd:dateTime ; dct:creator </user/jhondoe#me> .
ex-5). The container is updated to with the binary resource as a member.
GET /Bug1/attachments/ HTTP/1.1 Host: exampl[1] - https://dev.twitter.com/docs/api/1.1/post/statuses/update_with_mediae.org Accept: text/turtle HTTP/1.1 200 OK Content-Type: text/turtle ETag: W/"123456789" </Bug1/attachments/> a ldp:Container ; rdfs:member </Bug1/login-page.png> .
ex-6). We can update the metadata about the binary resource using the metadata URI
PUT /Bug1/attachments/attachment1 HTTP/1.1 Host: example.org Content-Type: text/turtle If-Match: W/"123456789" </Bug1/attachments/attachment1> x:content </Bug1/attachments/login-page.png> ; </Bug1/attachments/login-page.png> ; dc:title "Screenshop of the Web UI of the login page when error happened"; dct:created "2013-05-27T17:05Z"^^xsd:dateTime ; dct:creator </user/jhondoe#me> . HTTP/1.1 204 No Content ETag: W/"123456790"
ex-7). We can delete the binary resource and the metadata LDPR must be automatically deleted.
DELETE /Bug1/attachments/login-page.png HTTP/1.1 Host: example.org HTTP/1.1 204 No Content ETag: W/"123456790"
Then if we retrieve
GET /Bug1/attachments/login-page.png HTTP/1.1 Host: example.org HTTP/1.1 410 Gone
and
GET /Bug1/attachments/attachment1 HTTP/1.1 Host: example.org HTTP/1.1 410 Gone
3.3.2 Ordering
3.3.3 In-lining
Alternatively, the servers can also inline the membership resources in the container representation.
HTTP/1.1 200 OK Content-Type: text/turtle ETag: W/"123456790" <http://example.org/app/BugTracker/ProductB> a ldp:Container, bt:Product; dcterms:title "A container that tracks bugs of Product B" ; rdfs:member <http://example.org/app/BugTracker/ProductB/Bug10> ; rdfs:member <http://example.org/app/BugTracker/ProductB/Bug11> ; rdfs:member <http://example.org/app/BugTracker/ProductB/Bug12> . <http://example.org/app/BugTracker/ProductB/Bug10> a bt:Bug; dcterms:title "Product B does not make coffee"; dcterms:creator <http://example.org/users/johndoe>; dcterms:created "2013-05-05T10:00"^^xsd:dateTime; bt:isInState "New"; <http://example.org/app/BugTracker/ProductB/Bug11> a bt:Bug; dcterms:title "Product B GUI is too reddish"; dcterms:creator <http://example.org/users/janeroe>; dcterms:created "2013-05-06T10:00"^^xsd:dateTime; bt:isInState "InProgress"; <http://example.org/app/BugTracker/ProductB/Bug12> a bt:Bug; dcterms:title "Product B is too slow"; dcterms:creator <http://example.org/users/johndoe>; dcterms:created "2013-05-07T10:00"^^xsd:dateTime; bt:isInState "InProgress";
3.3.4 Paging
4 LDP Implementations
A list of implementations that plan to be LDP compliant is available in the LDP Implementations wiki page.
LDP Implementation report provides the coverage of the specification by each LDP implementation.
5 Mapping with other documents (to be removed)
5.1 Use Case and Requirements
Mappings to UCR document | ||
---|---|---|
UCR Use Cases | Primer Example | |
4.1 Manage containers | 4.1.1 create container | 4.1 |
4.1.2 create a nested container | ||
4.2 Manage resources | 4.2.1 create resource | 4.2 |
4.2.2 delete resource | 4.5 | |
4.2.3 moving contained resources | ||
4.3 Retrieve resource description | 4.3.1 Retrive | 4.3 |
4.3.2 retrieve description of a non-document resource | ||
4.4 Update existing resource | 4.4.1 enrichment | 4.4 |
4.4.2 selective update of a resource | 4.4 | |
4.5 Determine if a resource has changed | 4.5.1 Determine if a resource has changed | |
4.6 Aggregate resources | 4.6.1 add a resource to a collection | |
4.6.2 add a resource to multiple collections | ||
4.7 Filter resource description | 4.7.1 retrieve collection-level description | |
4.7.2 Alternative scenario: retrieve item-level description of a collection | ||
4.8 Manage media resources | 4.8.1 access media resources | |
4.8.2 media-resource attachments |
5.2 Test cases document
Mappings to Test Cases document | ||
---|---|---|
UCR Use Cases | Primer Example | |
TC-R1. GET on an LDPR | 4.3 | |
TC-R2. GET on an LDPR without content type | ||
TC-R3. GET on a non-existing LDPR | ||
TC-R4. PUT on an LDPR | 4.4 | |
TC-R5. PUT on an LDPR without matching ETags | ||
TC-R6. DELETE on an LDPR | 4.5 | |
TC-R7. HEAD on an LDPR | 4.4 | |
TC-C1. GET on an LDPC | 4.6 | |
TC-C3. GET on a non-existing LDPC | ||
TC-C4. PUT on an LDPC | 4.7 | |
TC-C5. PUT on an LDPC without matching ETags | ||
TC-C6. DELETE on an LDPC | 4.8 | |
TC-C7. DELETE on an LDPR in an LDPC | ||
TC-C8. HEAD on an LDPC | 4.4 | |
TC-C9. POST an LDPR on an LDPC | 4.2 |
5.3 Not covered in UCR and Tests
- Ordering
- Paging
- Inlining
6 References
[TURTLE] David Beckett; Tim Berners-Lee. Turtle: Terse RDF Triple Language. February 2013. W3C Candidate Recommendation. URL: http://www.w3.org/TR/turtle/
7 Appendix
7.1 Example Ontology (to be removed)
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>. @prefix owl: <http://www.w3.org/2002/07/owl#> . @prefix xsd: <http://www.w3.org/2001/XMLSchema#"> . @prefix dcterms: <http://purl.org/dc/elements/1.1/> . @prefix foaf: <http://xmlns.com/foaf/0.1/>. @prefix bt: <http://example.org/vocab/bugtracker#> . bt:Ontology a owl:Ontology; rdfs:label "Bug Tracker Example Ontology"; rdfs:comment "An ontology for Bug Tracker example in the LDP Primer" . bt:tracksProject a owl:ObjectProperty; rdfs:domain bt:BugTracker; rdfs:range bt:Product . bt:hasBug a owl:ObjectProperty; rdfs:domain bt:Product; rdfs:range bt:Bug . bt:isInState a owl:ObjectProperty; rdfs:domain bt:Bug; rdfs:range xsd:string . bt:relatedBug a owl:ObjectProperty; rdfs:domain bt:Bug; rdfs:range bt:Bug . bt:Product a owl:Class; owl:subClassOf [ a owl:Restriction ; owl:onProperty dcterms:title; owl:qualifiedCardinality "1"^^xsd:nonNegativeInteger ; owl:onDataRange xsd:string ] . bt:Bug a owl:Class; owl:subClassOf [ a owl:Restriction ; owl:onProperty dcterms:created; owl:qualifiedCardinality "1"^^xsd:nonNegativeInteger ; owl:onDataRange xsd:dateTime ]; owl:subClassOf [ a owl:Restriction ; owl:onProperty dcterms:creator; owl:qualifiedCardinality "1"^^xsd:nonNegativeInteger ; owl:onClass foaf:Person ]; owl:subClassOf [ a owl:Restriction ; owl:onProperty dcterms:title; owl:qualifiedCardinality "1"^^xsd:nonNegativeInteger ; owl:onDataRange xsd:string ]; owl:subClassOf [ a owl:Restriction ; owl:onProperty bt:isInState; owl:qualifiedCardinality "1"^^xsd:nonNegativeInteger ; owl:onDataRange xsd:string ] .
8 Temporary
8.1 Basic concepts and terminology
8.1.1 LDPR
- LDPRs are HTTP resources that can be created, modified, deleted and read using standard HTTP methods (i.e., POST, PUT/PATCH, DELETE, GET).
- LDPRs use RDF to define their states.
- You can request a Turtle representation of a LDPR and possibly other representations (e.g., XML/RDF)
- LDP clients use Optimistic Collision Detection on update.
- LDPRs set rdf:type explicitly.
- LDP clients expect to encounter unknown properties and content.
- LDP clients do not assume the type of a resource at the end of a link.
From WWW LDP presentation
8.1.2 LDPC
- LDPCs are LDPRs
- Clients can retrieve the list of resource members of an LDPC using GET
- New resources are created using POST
- Any resource can be POSTed to an LDPC – not just LDPRs
- After POSTing a new resource to an LDPC, the new resource will appear as a member untilit is deleted.
- Clients can retrieve information about an LDPC without retrieving a full representation of its content, including its members.
- On deleting an LDPC the server MAY delete member resources.
From WWW LDP presentation