RE: ldp-ISSUE-20 (POSTed resources): Identifying and naming POSTed resources [Use Cases and Requirements]



This use-case is about creating an RDF resource within a container using


The issue to be determined boils down to 'what is the base URI of a POSTed


In Turtle URIs in angle brackets may be relative URIs (relative to the
base), so '<>' is the base URI itself.

However, depending on how you interpret the standards, the base URI might be
the URI of the container or the URI of the resource. 

Whichever it is we have solutions (A) and (B) below. 

In either case the response is 201 Created with the 'Location' header
identifying the new resource.


A) The base URI is the URI of the resource:

This is in many ways the neater solution. It is less verbose and has the
advantage that we can refer directly to the resource.


<> a foaf:PersonalProfileDocument;

   foaf:primaryTopic <#me> .


<#me> a foaf:Person;

     foaf:name "Henry" .



B) The base URI is the URI of the container:

This approach requires the container to Skolemize the anonymous resource
(See <>).


<> rdfs:member [

      a helios_bt:BugtrackerIssue;

      dc:identifier "58365";

      dc:type           "bug";



I would have used the same example, but since (in this interpretation) the
URI of the resource isn't known until it is created, we would have to make
assertions about #me in a separate step.

This also has the slightly ugly disadvantage that the client needs to know
and use the membership predicate (rdfs:member).


The Standards



RFC 3986: Uniform Resource Identifier (URI): Generic Syntax


5.1.  Establishing a Base URI

The base URI of a reference can be established in one of four ways,
discussed below in order of precedence:


1. Base URI Embedded in Content

2. Base URI of the encapsulating entity

3. URI used to retrieve the entity

4. Default Base URI (application-dependent)


In the context of an RDF POST:

1. For example, the current base URI may be altered in a Turtle document
using the @base directive.

2. For a document that is enclosed within another entity, such as a message
or archive, the retrieval context is that entity.

3. For a POST there is no retrieval URI.

4. The default can be determined by the Linked Data Platform.


My reading of this is that in the absence of an embedded @base, for a
resource in a container, the retrieval context is the container.

This would be identical with the request URI.


RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1


9.5 POST

"The actual function performed by the POST method is determined by the

   server and is usually dependent on the Request-URI. The posted entity

   is subordinate to that URI in the same way that a file is subordinate

   to a directory containing it, a news article is subordinate to a

   newsgroup to which it is posted, or a record is subordinate to a



This isn't really much help. It reinforces the idea that the posted resource
is subordinate to the container identified by the request-URI. Yet it
doesn't define the base URI for the subordinate entity.


14.14 Content-Location

   "The value of Content-Location also defines the base URI for the entity."

   However.. "The meaning of the Content-Location header in PUT or POST
requests is undefined"


My reading of this is inconclusive.





Steve Battle
Semantic Engineer

Mobile: +44 (0)7503 624 613

E-mail:  <>
Web:  <>


Sysemia Limited
The Innovation Centre, Bristol &  Bath Science Park, Dirac Crescent,
Emerson's Green, Bristol BS16 7FR
Registered in England and Wales. Company Number: 7555456


Information contained in this e-mail is intended for the use of the
addressee only, and is confidential and may also be privileged. If you
receive this message in error, please advise us immediately. If you are not
the intended recipient(s), please note that any form of distribution,
copying or use of this communication or the information in it is strictly
prohibited and may be unlawful. Attachments to this e-mail may contain
software viruses which may damage your systems. Sysemia Ltd have taken
reasonable steps to minimise this risk, but we advise that any attachments
are virus checked before they are opened.


From: Henry Story [] 
Sent: 09 October 2012 10:36
To: Linked Data Platform (LDP) Working Group
Subject: Re: ldp-ISSUE-20 (POSTed resources): Identifying and naming POSTed
resources [Use Cases and Requirements]



On 8 Oct 2012, at 19:35, Henry Story <> wrote:

On 8 Oct 2012, at 11:52, Linked Data Platform (LDP) Working Group Issue
Tracker <> wrote:

ldp-ISSUE-20 (POSTed resources): Identifying and naming POSTed resources
[Use Cases and Requirements]

Raised by: Steve Battle
On product: Use Cases and Requirements

Regarding use-case :

esources> raises questions about POSTed resources.

* How is the inserted resource identified?
The use-case scenario assumes that the inserted resource is identified by
including its relation via the membership predicate, to the membership

<> rdfs:member [
    a helios_bt:BugtrackerIssue;
    dc:identifier           "58365";
    dc:type      "bug";
    helios_bt:isInBugtracker eg:bugtracker

* How does the created resource relate to the RDF description? 
See user-story
< POSTed

The example above assumes that the object of the insert is an anonymous
(existentially quantified) resource that can be skolemized to produce a URI
that can be returned in the Location header.

e.g. The response the the POST

HTTP/1.1 201 Created
ETag: W/"1234567890"

I think the answer to this problem is simple and requires some text in
section 4.3

to the effect that: one should POST an RDF document to a collection with
URIs such that the relatives URIs in the document will be resolve relative
to the 
URI created by the server for that resource.

So if you post

<> a foaf:PersonalProfileDocument;
  foaf:primaryTopic <#me> .

<#me> a foaf:Person;
    foaf:name "Henry" .

to a collection 


then the server will create a resource http://profile.example/2012/93
against which the above document with relative URLs will be resolved
so that one ends up with a document which is isomorphic to

<http://profile.example/2012/93> a foaf:PersonalProfileDocument;
  foaf:primaryTopic <#me> .

<http://profile.example/2012/93#me> a foaf:Person;
    foaf:name "Henry" .


Btw, I had implemented this a while ago here, so it does work, and pretty
nicely too:


WriteWeb.scala#l150>  150 case POST(_) & RequestContentType(ct) if
representation == DirectoryRepr =>

WriteWeb.scala#l151>    151               val createType =
WriteWeb.scala#l152>    152               r.create(createType) failMap { t
=> NotFound ~> ResponseString(t.getStackTraceString)} flatMap { rNew =>
WriteWeb.scala#l153>    153                 Post.parse(,, ct) match {
WriteWeb.scala#l154>    154                   case PostRDF(model) => {
WriteWeb.scala#l155>    155           "RDF content:\n"
+ model.toString())
WriteWeb.scala#l156>    156                     for {
WriteWeb.scala#l157>    157                       _ <-
failMap {
WriteWeb.scala#l158>    158                         t => InternalServerError
~> ResponseString(t.getStackTraceString)
WriteWeb.scala#l159>    159                       }
WriteWeb.scala#l160>    160                     } yield Created ~>
WriteWeb.scala#l161>    161                   }
WriteWeb.scala#l162>    162                   case PostBinary(is) => {
WriteWeb.scala#l163>    163                     for (_ <- rNew.putStream(is)
failMap { t=> InternalServerError ~> ResponseString(t.getStackTraceString)})
WriteWeb.scala#l164>    164                     yield Created ~>
WriteWeb.scala#l165>    165                   }
WriteWeb.scala#l166>    166                   case _ => {
WriteWeb.scala#l167>    167           "Couldn't parse
the request")
WriteWeb.scala#l168>    168                     (BadRequest ~>
ResponseString("You MUST provide valid content for given Content-Type: " +
WriteWeb.scala#l169>    169                   }
WriteWeb.scala#l170>    170                 }
WriteWeb.scala#l171>    171               }
WriteWeb.scala#l172>    172


rNew is the new resource created in the collection.

Post.parse parses the inputstream and de-relativises all URLs to the new

( Of course one would get the same effect if one just placed the unparsed
document at that location with its relative urls )


so the advantage of this is that it does not even require the rdf to be
parsed to work correctly.



* Should POST support a user supplied local-name 'hint'; e.g. based on the
supplied rdfs:label, to support more human-readable URIs?

yes, Atom has something on this I think

If it is good enough one should probably use that as they spent enormous
amounts of time
discussing that.

Alternatively, an owl:sameAs could be used in the above to provide a
user-friendly name.

Social Web Architect


Social Web Architect


Received on Tuesday, 9 October 2012 10:39:31 UTC