Re: Example of Atom publication using LDP

hello henry.

thanks for taking the lead here, i was in the process of cobbling together
some turtles, but then again you're much better at this than myself, so
thanks for the effort.

On 2013-01-30 12:40 , "Henry Story" <henry.story@bblfish.net> wrote:
>1. POSTing Content
>==================
>
>Now we post an Atom entry using the AtomOWL ontology,
>with some obvious simplifications.
>
>-----------------------------------------------
>POST / HTTP/1.1
>...
>
>@prefix : <http://bblfish.net/work/atom-owl/2006-06-06/#> .
>
> <> :Entry;
>    :author <http://joe.example/#i>;
>    :title "Atom Powered Robots Run Amok";
>    :id "urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a"^^xsd:anyURI;
>    :updated "2013-01-13T18:30:02Z"^^xsd:dateTime;
>    :summary "Some text.";
>    :content "Some text or other content - of course the mime type of the
>content needs to be specified" .
>-------------->>
>HTTP/1.1 201 Created
>Content-Type: text/turtle

i'd prefer to expose what we're doing on the uniform interface level by
using application/ldp+turtle, but i know this is controversial.

[[ as a side note, http://tools.ietf.org/html/rfc6839 was published today
and maybe somebody would be interested to make popular RDF syntaxes
visible at that level, registering at least +rdfxml and +turtle and maybe
others as well. ]]

as an alternative, i'd propose text/turtle;profile=http://w3.org/ldp so
that we have our protocol represented somehow, but even this would require
for the turtle media type to support profiles (which it currently doesn't).

>Link: <http://bblfish.net/work/atom-owl/2006-06-06/#Entry>;
>rel="http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
>Location: <entry1>
>...
>-----------------------------------------------
>
>Note that in the Atom Protocol RFC5023 they mix the content type
>and the returned type of the content. In section 9.2.1
>they show the 201 created returns a Content-Type of:
>
> Content-Type: application/atom+xml;type=entry;charset="utf-8"
>
>( https://tools.ietf.org/html/rfc5023#section-9.2.1 )
>
>Given that we don't want to make the same mistake of mixing
>syntax and semantics as the AtomPub protocol did I have moved
>the type to a link element. Then say if Twitter abandonds one
>format - as it recently abandoned Atom XML in favor of JSON
>http://www.mguhlin.org/2012/09/darn-its-happened-again-abandoning.html -
>then the protocol will have no problem and still be able to adapt
>itself.
>
>Note that this would create a new entry in the ldp:Container, of type
>:Entry
>which one could find out by doing a GET on the container:


so far so good. i don't quite understand the mistake you claim to see in
the media type parameter, but that's a minor issue.

>-----------------------------------------------
>GET / HTTP/1.1
>-------------->>
>
>@prefix : <http://bblfish.net/work/atom-owl/2006-06-06/#> .
>
><> a ldp:Container;
>   rdfs:member [ owl:sameAs </entry1>;
>                 a :Entry;
>                 :author  <http://joe.example/#i>;
>                 :title "Atom Powered Robots Run Amok";
>                 :id
>"urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a"^^xsd:anyURI;
>                 :updated "2013-01-13T18:30:02Z"^^xsd:dateTime;
>                 :summary "Some text." ] .
>-----------------------------------------------
>
>Notice that the ldp:Container does not show all the information: for
>example it does not show the content. To do that one has to
>GET </entry1> like this:

it would be up to us to decide how to expose this. LDP could decode
whatever it wants. atom exposes embedded content when you GET a feed, and
it also exposes the link to "external" content when you GET a feed, so
there's no need there for an extra GET. strictly speaking, atom is kind of
fuzzy there and doesn't really specify if and how representations of
entries differ when they occur in a feed, or as standalone resources. but
implementation-wise, the answer most often is: they don't differ.

>-----------------------------------------------
>GET /entry1 HTTP/1.1
>------------------->>
>
>@prefix : <http://bblfish.net/work/atom-owl/2006-06-06/#> .
>
><> a :Entry;
>   :author  <http://joe.example/#i>;
>   :title "Atom Powered Robots Run Amok";
>   :id "urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a"^^xsd:anyURI;
>   :updated "2013-01-13T18:30:02Z"^^xsd:dateTime;
>   :summary "Some text.";
>   :content "Some text or other content - of course the mime type of the
>content needs to be specified ." .
>-----------------------------------------------
>
>So to DELETE </entry1> would delete also the rdfs:member information in
>the
><http://atom.example/> container, with of course all the metadata about
>it.
>
>
>2. POSTing a link to another resource
>=====================================
>
>Next we want to post a link to something without content
>
>-----------------------------------------------
>POST / HTTP/1.1
>...
>
>@prefix : <http://bblfish.net/work/atom-owl/2006-06-06/#> .
>
> <> :Entry;
>    :author <http://joe.example/#i>;
>    :title "picture of a cat";
>    :updated "2013-01-13T18:45:23Z"^^xsd:dateTime;
>    :summary "Cat with a funny hat made of bread";
>    :content <http://cat.example/cat1.jpg> .
>-----------------------------------------------
>
>So this creates a resource <entry2> which which contains exactly what
>was POSTed as in the example with the content. A GET on the container
>now has the following ( assuming we have not deleted </entry1> yet of
>course )
>
>-----------------------------------------------
>GET / HTTP/1.1
>------------->>
>
>@prefix : <http://bblfish.net/work/atom-owl/2006-06-06/#> .
>
><> a ldp:Container;
>   rdfs:member [ owl:sameAs </entry1>;
>                 a :Entry;
>                 :author  <http://joe.example/#i>;
>                 :title "Atom Powered Robots Run Amok";
>                 :id
>"urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a"^^xsd:anyURI;
>                 :updated "2013-01-13T18:30:02Z"^^xsd:dateTime;
>                 :summary "Some text." ],
>               [ owl:sameAs </entry2>;
>                 a :Entry;
>                 :author <http://joe.example/#i>;
>                 :id "http://atom.example/entry2";
>                 :title "picture of a cat";
>                 :updated "2013-01-13T18:45:23Z"^^xsd:dateTime;
>                 :summary "Cat with a funny hat made of bread";
>                 :content <http://cat.example/cat1.jpg>  .
>  
>-----------------------------------------------
>
>Now again deleting </entry2> deletes it from the container
><http://atom.example/> but does not delete the content.

it's a bit inconsistent here because the embedded content does not show
up, but the content link is exposed. i'd rather see this being consistent,
but again, that's a detail.

> 
>3. POSTING Binary Content
>=========================
>
>So here we post some binary content onto the container
>at <http://atom.example/>
>
>-----------------------------------------------
>POST / HTTP/1.1
>Slug: mouse
>Content-Type: image/gif
>Content-Length: 1024
>...
>-----------------------------------------------
>
>The result is meant to be that the server will create
>a binary and an atom entry about that published resource.

and the response of the POST will specify the newly created entry URI.

>-----------------------------------------------
>GET / HTTP/1.1
>-------------->>
>
>@prefix : <http://bblfish.net/work/atom-owl/2006-06-06/#> .
>
><> a ldp:Container;
>   rdfs:member [ owl:sameAs <entry1>;
>                 a :Entry;
>                 :author  <http://joe.example/#i>;
>                 :title "Atom Powered Robots Run Amok";
>                 :id
>"urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a"^^xsd:anyURI;
>                 :updated "2013-01-13T18:30:02Z"^^xsd:dateTime;
>                 :summary "Some text." ],
>               [ owl:sameAs <entry2>;
>                 a :Entry;
>                 :author <http://joe.example/#i>;
>                 :id "http://atom.example/entry2";
>                 :title "picture of a cat";
>                 :updated "2013-01-13T18:30:02Z"^^xsd:dateTime;
>                 :summary "Cat with a funny hat made of bread";
>                 :content <http://cat.example/cat1.jpg> ],
>               [ owl:sameAs <entry3>;
>                 a :Entry;
>                 :author <http://joe.example/#i>;
>                 :id "http://atom.example/entry3";
>                 :title "mouse";
>                 :updated "2013-01-13T19:10:02Z"^^xsd:dateTime;
>                 :content <mouse.gif> ].
>-----------------------------------------------
>
>Here DELETEing <entry3> may or may not also delete <cat.gif> or
>vice-versa. I am not sure.

the idea would be that these two resources are tightly coupled by virtue
of having been created together. in atom, you would see the difference
because there would be an edit-media link in the mouse metadata resource,
which would expose the interaction affordances (the link definition
http://tools.ietf.org/html/rfc5023#section-11.2 says you can use that link
to GET, PUT, DELETE) for the mouse.gif resource. this is something that
only can be done for media resources, because for "externally linked"
resources, the LDP server wouldn't be able to provide these affordances.

>But a GET on <entry3> would return
>
>-----------------------------------------------
>GET /entry3 HTTP/1.1
>-------------------->>
>
>@prefix : <http://bblfish.net/work/atom-owl/2006-06-06/#> .
>
> <> :Entry;
>    :author <http://joe.example/#i>;
>    :title "mouse";
>    :updated "2013-01-13T19:10:02Z"^^xsd:dateTime;
>    :content <mouse.gif> .
>-----------------------------------------------
>
>Ok, so that seems to be along the lines of what
>it would take to include Atom as part of LDP.

thanks, i think this is very close to what i was trying to do (and i am
sure my examples would have had many errors).

what might be interesting to look at as well is the extensible metadata
model. some properties (in this example the atom properties "updated" and
so forth) are specified by the protocol, and have protocol-defined meaning
(and constraints). some of these are mandatory, some are optional (in
certain interactions).

in addition to protocol-defined properties, there are additional metadata
fields, which clients are free to submit as well. they must be about the
resource they are interacting with, or the request is invalid. i guess the
RDF constraint there would be to say that clients can add arbitrary graphs
of metadata, as long as they are "anchored" at the resource they are
interacting with. this would allow simple as well as structured metadata
to be managed via LDP.

so now that henry has taken the time to RDFify this proposal: i still
think that this provides a simple and effective way to support and even
combine "composition" and "aggregation", and that the model also allows us
to elegantly define how the deletion semantics work. you DELETE what you
have POSTes, and that's all there is to say.

please keep in mind that atom and atompub do not support hierarchies.
there have been attempt to do this (of myself as well as of others), but
nothing ever gained traction, afaik. since we seem to be on track to have
hierarchical collections, that would be an added complication to this
model.

what's also interesting to look at is paging. in the simple model of
RFC5005, paging is simply exposed as "next" and "pref" links in the
collection: if you know those link relations, you know how to page through
a feed. this is simple and purely link-based and thus easy to use. in a
more complex scenario, when you want to allow interactions to make more
specific requests such as specifying a paging size, or jumping to a
specific page, then we have to think about how to expose this. typically,
URI templates are used for this kind of functionality, and as long as LDP
specifies a fixed number of variables to use, maybe we could solve that
problem fairly easily.

cheers,

dret.

Received on Wednesday, 30 January 2013 13:20:17 UTC