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

On 8 Oct 2012, at 19:35, Henry Story <henry.story@bblfish.net> wrote:

> 
> On 8 Oct 2012, at 11:52, Linked Data Platform (LDP) Working Group Issue Tracker <sysbot+tracker@w3.org> wrote:
> 
>> ldp-ISSUE-20 (POSTed resources): Identifying and naming POSTed resources [Use Cases and Requirements]
>> 
>> http://www.w3.org/2012/ldp/track/issues/20
>> 
>> Raised by: Steve Battle
>> On product: Use Cases and Requirements
>> 
>> Regarding use-case : <http://www.w3.org/2012/ldp/wiki/Use_Cases_And_Requirements#UC-BPC2:_Create_resource_within_a_container>
>> 
>> User-story <http://www.w3.org/2012/ldp/wiki/Use_Cases_And_Requirements#Hosting_POSTed_Resources> 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 subject.
>> e.g.
>> 
>> <> 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 <http://www.w3.org/2012/ldp/wiki/Use_Cases_And_Requirements#Hosting POSTed Resources>.
>> 
>> 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
>> Location: http://example.com/bugtracker/a0001
>> ETag: W/"1234567890"
> 
> 
> I think the answer to this problem is simple and requires some text in section 4.3
> http://www.w3.org/2012/ldp/hg/ldbp.html#http-post
> 
> to the effect that: one should POST an RDF document to a collection with relative 
> 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 
> 
> http://profile.example/2012/
> 
> 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:

https://dvcs.w3.org/hg/read-write-web/file/258d2757ef3d/src/main/scala/ReadWriteWeb.scala#l150

   150 case POST(_) & RequestContentType(ct) if representation == DirectoryRepr =>
   151               val createType = Representation.fromAcceptedContentTypes(List(ct))
   152               r.create(createType) failMap { t => NotFound ~> ResponseString(t.getStackTraceString)} flatMap { rNew =>
   153                 Post.parse(Body.stream(req), rNew.name, ct) match {
   154                   case PostRDF(model) => {
   155                     logger.info("RDF content:\n" + model.toString())
   156                     for {
   157                       _ <- rNew.save(model) failMap {
   158                         t => InternalServerError ~> ResponseString(t.getStackTraceString)
   159                       }
   160                     } yield Created ~> ResponseHeader("Location",Seq(rNew.name.toString))
   161                   }
   162                   case PostBinary(is) => {
   163                     for (_ <- rNew.putStream(is) failMap { t=> InternalServerError ~> ResponseString(t.getStackTraceString)})
   164                     yield Created ~> ResponseHeader("Location",Seq(rNew.name.toString))
   165                   }
   166                   case _ => {
   167                     logger.info("Couldn't parse the request")
   168                     (BadRequest ~> ResponseString("You MUST provide valid content for given Content-Type: " + ct)).success
   169                   }
   170                 }
   171               }
   172

rNew is the new resource created in the collection.
Post.parse parses the inputstream and de-relativises all URLs to the new url. 
( 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.

Henry

> 
> 
> 
> 
>> 
>> 
>> * 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 
> http://tools.ietf.org/html/rfc5023#section-9.7
> 
> 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
> http://bblfish.net/
> 

Social Web Architect
http://bblfish.net/

Received on Tuesday, 9 October 2012 09:36:28 UTC