UNAPPROVED DRAFT
OSLC Core Guidance: Links & Relationships
By: the OSLC Core Workgroup
In this guidance we offer advice to OSLC workgroups on modeling links and relationships between OSLC resources.
Relationships in OSLC
The Core workgroup's guidance to OSLC domain workgroups is that relationships are uni-directional and in most cases relationships should be modeled as links. We offer two ways to express relationships, a link and an anchor. Let's define those terms and others that we will use in this document:
- Relationship: a relationship is said to exist between two resources if there is something that connects them; they work together, belong together, are similar or should be considered together. There may be different types of relationships.
- Link: a link is a URI reference from one resource, the source, to another resource, said to be the target. In RDF and in OSLC we use links to model relationships and like relationships, links are uni-directional.
- Anchor: an anchor is a mechanism for attaching property-values to a link, thus annotating a relationship with values that are about that relationship.
Now that we've defined our terminology, let's move on to expressing relationships.
Two ways to express relationships in OSLC
The RDF data model gives us a number of value-types to express relationships, some more complex than others. We expect that the majority of links will be expressed with the most simple option, URI Reference or as it is known in conversation, a Link. For more complex cases, when a relationship must be annotated with property-values, we use what is called an Anchor. Read the sub-sections below for details and examples of Links and Anchors.
1) Link
Link from source to target.
Use this when you need a simple link, you don't want to inline any summary of the target and you do not need to annotate the link with property values. Most relationships should be represented this way.
In RDF terminology, a link is called a URI Reference. In OSLC, you express a link as a property with OSLC value-type of
Resource and OSLC representation of
Reference. For example, here is a property
oslc_blog:attachment
that you might find inside a blog entry, it links to a resource that is "attached" to the blog entry:
Example #1: relationship expressed as simple link (i.e. URI reference)
<!-- OSLC Core value-type is Resource Reference -->
<oslc_blog:attachment rdf:resource="http://example.com/attachments/2" />
When you specify value-type Resource with representation Reference, you can specify a
Range if you want to restrict what is linked to, but you don't have to and you should think very carefully about any restrictions you place. Ideally, anything should be able to link to anything.
2) Anchor
Local Resource holds link from source to target plus property-values that annotate the relationship.
Relationships are expressed as RDF triples and triples do not have property values - only resources have property values. Links are used to express relationships. Many relationships can be represented by a single link, but some relationships need to be
annotated with property values. For example, if I am trying to represent the subscriber relationship between a customer and a magazine, I may need to record an expiration date for the relationship. To do this, we need to use an RDF concept known as
reification. Reification is a way to make a statement about a statement. See
RDF Syntax Specification Section 4: Statements about Statements for more information on this concept (reference:
RDF Syntax).
Assuming the subscriber scenario, example #2 shows how you would use reification to express the annotation.
Note that this example follows OSLC Core guidance for forming RDF/XML representations, except that each link that must be annotated has an
rdf:ID
attribute for each of those there is an
rdf:Description
element outside of the resource representation but inside the
rdf:RDF
root element.
Link to validation, triples and graph:
http://tinyurl.com/jimc-link2
Example #2: Link as reified statement in RDF/XML format
<rdf:RDF
xmlns:terms="http://example.com/terms/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<terms:Customer rdf:about="http://example.com/customers/4321">
<terms:subscribesTo rdf:ID="n1"
rdf:resource="http://example.com/magazines/Field_and_Stream" />
</terms:Customer>
<rdf:Description rdf:about="#n1">
<terms:expirationDate>2010-06-03</terms:expirationDate>
</rdf:Description>
</rdf:RDF>
Design Notes:
There are some subtleties and complexities of this design that we need to keep in mind. One in particular is that our representation in Example 2 illustrates use of a special capability that is unique to RDF/XML and does not have an analog in Ntuples, Turtle or N3. You can express exactly the same RDF in those formats, but the RDF/XML, as well as being more convenient, appears to imply more than is really true. Let's take the original RDF/XML:
<rdf:RDF
xmlns:terms="http://example.com/terms/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<terms:Customer rdf:about="http://example.com/customers/4321">
<terms:subscribesTo rdf:ID="n1"
rdf:resource="http://example.com/magazines/Field_and_Stream" />
</terms:Customer>
<rdf:Description rdf:about="#n1">
<terms:expirationDate>2010-06-03</terms:expirationDate>
</rdf:Description>
</rdf:RDF>
The RDF/XML would lead you to believe that there is some sort of connection between the Description and the triple established by line 6. In fact, there is none, and this XML can be rewritten with no change in meaning as this:
<rdf:RDF
xmlns:terms="http://example.com/terms/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<terms:Customer rdf:about="http://example.com/customers/4321">
<terms:subscribesTo rdf:resource="http://example.com/magazines/Field_and_Stream" />
</terms:Customer>
<rdf:Statement rdf:about="#n1">
<terms:expirationDate>2010-06-03</terms:expirationDate>
<rdf:subject rdf:resource="http://example.com/customers/4321"/>
<rdf:object rdf:resource="http://example.com/magazines/Field_and_Stream"/>
<rdf:predicate rdf:resource="http://example.com/terms/subscribesTo" />
</rdf:Statement>
</rdf:RDF>
The same example in Turtle format:
<http://example.com/customers/1234>
a customer;
subscribesTo <http://example.com/magazines/Field_and_Stream>.
<#n1> a Subscription;
expirationDate "2010-06-30";
rdf:object <http://example.com/magazines/Field_and_Stream>;
rdf:subject <http://example.com/customers/1234>;
rdf:predicate subscribesTo.
The important point is that the original RDF/XML makes it look as though you are adding a triple (expirationDate) whose subject is another triple <terms:subscribesTo... This is not the case - you are adding a property to a separate statement entity that is in no way connected to the triple except by the fact it shares the same predicate and object value.
And here's how to express the same within the JSON format specified by OSLC Core. Because we already represent value-type Resource as a JSON object, we can simply add annotating property-values directly into that. In this case, adding
terms:expirationDate
to the
terms:subscribesTo
object.
Example #3: Link as reified statement in OSLC JSON format
{
"prefixes" : {
"terms": "http://example.com/terms/",
"oslc": "http://open-services.net/ns/core#",
"rdf" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
},
"oslc:qname" : "terms:Customer",
"rdf:about" : "http://example.com/customers/4321",
"rdf:type" : { "rdf:resource" : "http://example.com/terms/customer" },
"terms:subscribesTo" : {
"rdf:resource" : "http://example.com/magazines/Field_and_Stream",
"terms:expirationDate" : "2010-06-03"
}
}
Anti-pattern: Link with inlined values of target
With the OSLC query syntax it is possible to get query resources with links and for each link some inlined values from the target of the link. This allows a client to get links and some information from the target of each link in one HTTP request per page of results, saving the client the expense of dereferencing each link. This pattern is useful for query, but is not recommended in OSLC resource design.
Below is an example of a link to a resource of type
oslc_blog:UploadedFile
and with the
dcterms:title
of that resource inlined. This enables the client to know the type and title of the target resource without having to HTTP GET it.
Anti-pattern Example: a link with inlined values of target
<oslc_blog:attachment rdf:about="http://example.com/attachments/2">
<oslc_blog:UploadedFile>
<dcterms:title>apache-wink-incubating-0.9.6.jar</dcterms:title>
</oslc_blog:UploadedFile>
</oslc_blog:attachment>
In OSLC defined resource terminology, the property above is type Resource with representation Inline. The problem with this is that it adds redundant property-values to a resource. When you link to a target resource that has a
dcterms:title
value and you inline that
dcterms:title
in the source resource, in the RDF data model this means that you have just given the target resource two titles. What if the titles do not match? Can a client change the title in the source resource?
That brings us to the end of the guidance. Please provide feedback to the OSLC Core Workgroup mailing-list:
References