Warning:
This wiki has been archived and is now read-only.

Primer

From Linked Data Platform
Jump to: navigation, search

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.

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.

A bit about Linked Data, current state, and the need for a Linked Data Platform (Read/Write LD) etc.
A bit about generic LDP servers and LDP servers that represent business applications. That is bit confusing for most of the people.

There will be several categories of systems implementing the LDP specification. Two main categories of the LDP servers include:

  1. 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.
  2. 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.

Note - Issue 46

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
Add a note on document/thing separation and when it matters. Link to URLs in Data

3.1 Simple Scenarios

3.1.1 Lookup a Product

Error 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 Bug

Error 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 Bug

Error 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 Bug

Error 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> . 
is this tracksproduct (rather than rdfs:member) ?

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)

BugTracker.jpg

 
 @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