Nametag: Hello, my name is Linked Data PlatformIn its ongoing mission to lead the World Wide Web to its full potential, the W3C recently released the first specification for an entirely new kind of system. Linked Data Platform 1.0 defines a read-write Linked Data architecture, based on HTTP access to web resources described in RDF. To put that more simply, it proposes a way to work with pure RDF resources almost as if they were web pages.

Because the Linked Data Platform (LDP) builds upon the classic HTTP request and response model, and because it aligns well with things like REST, Ajax, and JSON-LD, mainstream web developers may soon find it much easier to leverage the power and benefits of Linked Data. It’s too early to know how big of an impact it will actually make, but I’m confident that LDP is going to be an important bridge across the ever-shrinking gap between todays Web of hyperlinked documents and the emerging Semantic Web of Linked Data. In today’s post, I’m going to introduce you to this promising newcomer by covering the most salient points of the LDP specification in simple terms. So, let’s begin with the obvious question…

 

What is a Linked Data Platform?

A Linked Data Platform is any client, server, or client/server combination that conforms in whole or in sufficient part to the LDP specification, which defines techniques for working with Linked Data Platform Resources over HTTP. That is to say, it allows Linked Data Platform Resources to be managed using HTTP methods (GET, POST, PUT, etc.). A resource is either something that can be fully represented in RDF or otherwise something like a binary file that may not have a useful RDF representation. When both are managed by an LDP, each is referred to as a Linked Data Platform Resource (LDPR), but further distinguished as either a Linked Data Platform RDF Source (LDP-RS) or a Linked Data Platform Non-RDF Source (LDP-NR).

Diagram of LDPRs

There is also a special type of resource called a Linked Data Platform Container (LDPC). Containers are useful for working with collections of resources, often of the same kind. For example, a client could access the URI of a container on an LDP at some academic university to list the courses in a curriculum. It might access another container to list faculty members and each faculty member may itself act as a container to courses taught. In this way, containers act as a sort of glue for assembling a model as well as access points for managing that model through HTTP. Those familiar with static websites comprised of folders and HTML files could think of a container as sort of like a folder. Let’s just say for now, however, that containers have higher ambitions. A container can be one of three types, an explanation to which is forthcoming.

Diagram of LDPCs

And that’s it, in a nutshell. An LDP simply defines a standard set of techniques used for creating clients and servers that work with RDF resources over HTTP. The scope of the LDP 1.0 specification is intentionally narrow, but additional specifications are expected to build upon this initial foundation. For example, the Linked Data Platform Working Group is already beginning to draft techniques for paging through large collections of resources and they are also discussing methods for access control.

Linked Data Platform Resources

Let’s imagine a software defect tracking system and take a look at what a Linked Data Platform RDF Source (LDP-RS) might look like. Below, the same resource (a “bug”) is expressed first in Turtle and then again in JSON-LD for comparison. LDP servers must provide a text/turtle representation whenever an HTTP Accept header isn’t suggesting some other content type. JSON-LD (application/ld+json) is also recommended for use in LDP implementations, but not required. Any of a variety of content types could represent the state of a resource depending on what an LDP server supports and what’s requested with HTTP content negotiation. In fact, there’s nothing that says an LDP server couldn’t very well present a generic HTML representation for user-friendly rendering in a client browser.

LDP RDF Source (expressed in Turtle):

@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix bt: <http://example.org/vocab/bugtracker#> .

</tracker/project1/defects/bug67> a bt:Bug;
  dcterms:title "Product A crashes when shutting down.";
  dcterms:creator </tracker/users/johndoe>;
  dcterms:created "2013-05-05T10:00"^^xsd:dateTime;
  bt:isInState "New" .

LDP RDF Source (expressed in JSON-LD):

{
  "@context": "https://dvcs.w3.org/hg/ldpwg/raw-file/default/ldp-primer/context.json",
  "@id": "/tracker/project1/defects/bug67",
  "dcterms:title": "Product A crashes when shutting down.",
  "dcterms:creator": { "@id": "/tracker/users/johndoe" },
  "dcterms:created": {
    "@type": "http://www.w3.org/2001/XMLSchema#dateTime",
    "@value": "2013-05-05T10:00:00"
  },
  "bt:isInState": "New"
}

In our defect tracking system, a bug like this might start as the entity body in an HTTP POST to a defects container of a given project. The LDP server may then mint and return a unique URI for the given resource (e.g. /tracker/project1/defects/{bug67}), which clients can later use to fetch the resource using HTTP GET.

Behind the scenes an LDP server may very well use SPARQL and a triplestore to manage resources, but clients need only contend with document-like representations managed through a REST API. As you can see, this is not far from the common paradigms that mainstream web developers are comfortable with. A popular library like jQuery could easily be used to make Ajax requests and parse the JSON-LD, for example. Every-day web developers will soon be able to link data in and across applications with old-hat familiarity.

Again, LDP Servers also support resources that cannot be represented in RDF such as images or zip files. So, in the case of our defect tracking system, screen-shots or archived log files could also be managed with the corresponding defect.

Linked Data Platform Containers

As the name implies, an LDP Container contains things. They don’t actually literally contain resources, but rather – they contain links to a set of resources. Basically, they represent collections. A container responds to client requests for creation, modification, and/or enumeration of its members. In other words, the URI that identifies a given container acts as an HTTP interaction point through which members and membership can be managed.

A container is also a Linked Data Platform RDF Source, so while it has a special function as a membership controller, it may also represent additional data that is valuable to the agents that access it. In other words, the container is also an LDP-RS and as such, may have a variety of triples defining properties specific to the resource it represents.

Basic Containers

Of the three variants of an LDP Container, the most basic is aptly named a Basic Container. As shown in the example below, a BasicContainer has an rdf:type of http://www.w3.org/ns/ldp#Container and the more specific type, http://www.w3.org/ns/ldp#BasicContainer (a ldp:Container, ldp:BasicContainer).

LDP Basic Container (expressed in Turtle):

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.
	
<http://example.org/alice/> a ldp:Container, ldp:BasicContainer;
  dcterms:title 'Alice’s data storage on the Web' ;
  ldp:contains <http://example.org/alice/foaf> , <http://example.org/alice/avatar> .		

The property, ldp:contains, defines a set of triples, maintained by the container, which are documents created by the container. In LDP terminology, these are called containment triples and they always bear the triple form of:

<LDPC URI> <ldp:contains> <document-URI>

Basic Containers provide the most straight-forward way to have generic storage in an LDP Server and for creating a containment hierarchy of arbitrary resources.

Direct Containers

A Direct Container has an rdf:type of http://www.w3.org/ns/ldp#Container and the more specific type, http://www.w3.org/ns/ldp#DirectContainer (a ldp:Container, ldp:DirectContainer). This type is more flexible than a Basic Container because its membership triples can be about subjects other than the container resource itself. In other words, a Direct Container can act as an HTTP interaction point for managing membership on some resource other than the container itself.

To illustrate how this works, let’s imagine a product catalog application where an Images container is used for the management of product images and where membership triples express the relationship between those images and the Product.

LDP Direct Container 1

The membership triples I’m referring to exist on the membership resource, which is the Product for which the container is managing member images. A Direct Container is defined with two additional properties from the ‘ldp’ namespace:

  • ldp:membershipResource – the resource that the container manages resources for. In the case of our example, this is the Product resource.
  • ldp:hasMemberRelation – defines the membership predicate, which is the property on the membership resource that is to be used as the predicate of all the container’s membership triples.

In the example below, both the container and the membershipResource are shown together in a single document, but they could just as well be separated.

Direct Container Example 1 (Turtle):

@prefix ldp: <http://www.w3.org/ns/ldp#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix pc: <http://example.org/vocab/productcatalog#> .

</catalog/img/> ldp:DirectContainer;
  ldp:membershipResource </catalog/img/#SKU41-2510>;
  ldp:hasMemberRelation pc:hasImage;
  dcterms:title "Description of product which is also an LDP-DC";
  ldp:contains 
     <img1>, 
     <img2>,
     <img6> .
  
</catalog/img/#SKU41-2510> a pc:Product;
  dcterms:title "Waterproof LED Flashlight";
  pc:hasImage 
     <img1>,
     <img2>,
     <img6> .

One of the most common patterns where Direct Containers are useful is when it’s necessary to manage different facets of a resource using multiple containers. Our product, for example, may have a collection of customer reviews in addition to images.

LDP Direct Container 2

In this case, an LDP-RS might have membership triples for pc:hasImage and membership triples for pc:hasReview as shown below.

</catalog/SKU41-2510> a pc:Product;
  dcterms:title "Waterproof LED Flashlight";
  pc:hasImage 
     <img1>, 
     <img2>, 
     <img6>;
  pc:hasReview 
     <review1>, 
     <review2>,
     <review_2014_07_06> .

Notice that for each pc:hasImage membership triple in the Product resource above, there is a corresponding ldp:contains triple in the Direct Container below.

</catalog/SKU41-2510/images/>
    a ldp:DirectContainer;
    ldp:membershipResource   </catalog/SKU41-2510>;
    ldp:hasMemberRelation    c:hasImage;
    ldp:contains
        <img1>;
        <img2>;
        <img6>.

Another container manages the membership triples for pc:hasReview. But notice that I’ve thrown you a curve-ball in the example below. There are three Product reviews, but only two in the Direct Container that manages pc:hasReview membership triples, which is shown below.

</catalog/SKU41-2510/reviews/>
    a ldp:DirectContainer;
    ldp:membershipResource   </catalog/SKU41-2510>;
    ldp:hasMemberRelation    c:hasReview;
    ldp:contains
        <review1>;
        <review2>.

The pc:hasReview triples might have existed on the Product resource before a Direct Container was created for that property. What I have illustrated here is that the Direct Container will only have containment triples for resources that were created by POSTing to it.

Indirect Containers

An Indirect Container has an rdf:type of http://www.w3.org/ns/ldp#Container and the more specific type, http://www.w3.org/ns/ldp#IndirectContainer (a ldp:Container, ldp:IndirectContainer). Indirect Containers are very similar to Direct Containers, except that Indirect Containers are also capable of having members whose URIs are based on the content of its contained documents rather than the URIs of the contained documents. This is achieved by adding a property to the container called ldp:insertedContentRelation, which defines a predicate that may exist in representations posted to the container. When the defined predicate exists within the content being posted, the object of that triple is used to define the member rather than the URI that is minted for the newly created resource.

We can use our product catalog application to illustrate a use case. Imagine, for example, that we need to be able to classify and organize our products with topics from a controlled vocabulary. Now let’s also suppose that these topics are from an enterprise taxonomy, which we ourselves do not control. Even if we’re allowed to store an inverse link on those topics that we use, we wouldn’t necessarily want to. If that were allowed, all the applications using the enterprise taxonomy would eventually overload the topic resources in the taxonomy with inverse relations.

It would be nice to be able to manage inverse relations in a way that’s localized to our application so that we can refer both to topics by product and to products by topic – all the while maintaining a relation to the real topics from the enterprise taxonomy. The Indirect Container, as shown in the example below, gives us the flexibility we need to achieve this.

# This is our Product, which can be classified by topics...
</catalog/SKU41-2510>
    a pc:Product;
    dcterms:title "Waterproof LED Flashlight";
    # The membership triples link to the real resource
    c:hasTopic
        <http://example.org/topics/handheld-flashlights>;
        <http://example.org/topics/camping-lights-and-lanterns>.
  
# Indirect Container (controller for managing the topics on our Product)...
</catalog/SKU41-2510/topics/>
    a                       ldp:IndirectContainer;
    ldp:membershipResource  </catalog/SKU41-2510>;
    ldp:hasMemberRelation   c:hasTopic;
    ldp:isMemberOfRelation  c:hasProduct;
    
    # The predicate of posted content from which to derive the object URI...
    ldp:insertedContentRelation     foaf:primaryTopic;
    # The containment triples keep a reference to the representation resource
    
    ldp:contains
        <topics/handheld-flashlights>;
        <topics/camping-lights-and-lanterns>.
 
# Locally represents a resource outside of this app's domain of control...
</topics/handheld-flashlights>
    a                   c:ProxyTopic;
    foaf:primaryTopic   <http://example.org/topics/handheld-flashlights>;
    c:hasProduct
        </catalog/SKU41-2510>.

In this example, we invented a ProxyTopic resource to use as local representations of topics in the enterprise taxonomy. Each ProxyTopic that we POST to the Indirect Container has a foaf:primaryTopic that links to a topic from the enterprise taxonomy. So, while the Indirect Container is creating ProxyTopic resources, the actual product resource links to the topics in the enterprise taxonomy. We can use the member relation (defined by ldp:hasMemberRelation) to get the topics by product and we can use the inverse property of the ProxyTopic resource (ldp:isMemberOfRelation) to get products by topic.

Summary

Linked Data Platform is a new W3C recommendation for HTTP-based (RESTful) application integration patterns using read/write Linked Data. In this article, we’ve explored the most salient points of the specification. We learned that LDPs work with RDF and non-RDF resources. We also learned about a special type of resource called a Linked Data Platform Container, which acts as an HTTP interaction point for managing collections and which can be one of three increasingly flexible types: BasicContainer, DirectContainer, and IndirectContainer. With this simple resource model under an HTTP-based architectural style, the Linked Data Platform promises to make Linked Data more readily accessible to mainstream web developers and, in turn, the World Wide Web.

What to Read Next

If you’re interested in learning more or perhaps even implementing an LDP client or server, consider the following related resources.

[Editor’s Note: Linked Data Platform will also be discussed in depth at the upcoming Semantic Technology & Business Conference in two sessions by Arnaud Le Hors (IBM) and Sandro Hawke (W3C).]

Implementations

The Linked Data Platform is very new, but implementations are already beginning to emerge. A community-managed list can be found on the LDP Implementations page of the LDP wiki.

 

About the Author

Cody Burleson Cody Burleson is an Enterprise Web Architect, I.T. innovator, and a co-founder of Base22. He participates with the Linked Data Platform Working Group of the W3C and advocates for Linked Data in the modern corporate enterprise. You can find similar material on his personal blog at codyburleson.com.