Child pages
  • ERAtomPub framework

To edit or add content to this Wiki, you can simply create a new account at http://wocommunity.org/account.

Skip to end of metadata
Go to start of metadata

Following some discussions about HATEOAS support, and my own playing with Google Data Protocol and CMIS, it might be useful to add a ERAtomPub framework on top of ERRest. This page is to track ideas on how to build that framework.

A AtomPub have an endpoint that will return one or more workspaces. The app:workspace element MUST contain one "atom:title" element (as
defined in RFC4287), giving a human-readable title for the
Workspace.

   The "app:collection" element describes a Collection.  The app:
   collection element MUST contain one atom:title element.

   The app:collection element MAY contain any number of app:accept
   elements, indicating the types of representations accepted by the
   Collection.  The order of such elements is not significant.

   The app:collection element MAY contain any number of app:categories
   elements.

The app:collection element MUST contain an "href" attribute, whose
value gives the IRI of the Collection.

The content of an "app:accept" element value is a media range as
defined in RFC2616. The media range specifies a type of
representation that can be POSTed to a Collection.

The app:accept element is similar to the HTTP Accept request-header
RFC2616. Media type parameters are allowed within app:accept, but
app:accept has no notion of preference – "accept-params" or "q"
arguments, as specified in Section 14.1 of RFC2616 are not
significant.

A value of "application/atom+xml;type=entry" MAY appear in any app:
accept list of media ranges and indicates that Atom Entry Documents
can be POSTed to the Collection. If no app:accept element is
present, clients SHOULD treat this as equivalent to an app:accept
element with the content "application/atom+xml;type=entry".

If one app:accept element exists and is empty, clients SHOULD assume
that the Collection does not support the creation of new Entries.

This is an example of making a GET request to the endpoint when AtomPub is activated in WordPress:

GET http://localhost/wordpress/wp-app.php/service

HTTP/1.1 200 OK
Content-Length: 703
Date: Sat, 07 Apr 2012 10:33:40 GMT
Server: Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.8 with Suhosin-Patch
X-Powered-By: PHP/5.3.8
Connection: close
Content-Type: application/atomsvc+xml

<?xml version="1.0" encoding="utf-8"?>
<service xmlns="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom">
  <workspace>
    <atom:title>Move to WO! Workspace</atom:title>
    <collection href="http://localhost/wordpress/wp-app.php/posts">
      <atom:title>Move to WO! Posts</atom:title>
      <accept>application/atom+xml;type=entry</accept>
      <categories href="http://localhost/wordpress/wp-app.php/categories" />
    </collection>
    <collection href="http://localhost/wordpress/wp-app.php/attachments">
      <atom:title>Move to WO! Media</atom:title>
      <accept>image/*</accept><accept>audio/*</accept><accept>video/*</accept>
    </collection>
  </workspace>
</service>

The same request to a CMIS repository (Alfresco 4) looks like this:

GET http://cmis.alfresco.com/cmisatom

Date: Fri, 06 Apr 2012 14:28:11 GMT
Server: Apache-Chemistry-OpenCMIS/0.6.0-SNAPSHOT
Cache-Control: private, max-age=0
Content-Type: application/atomsvc+xml
Vary: Accept-Encoding
Connection: close
Transfer-Encoding: chunked

<?xml version='1.0' encoding='UTF-8'?>
<app:service xmlns:app="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:cmis="http://docs.oasis-open.org/ns/cmis/core/200908/" xmlns:cmisra="http://docs.oasis-open.org/ns/cmis/restatom/200908/">
	<app:workspace>
		<atom:title>371554cd-ac06-40ba-98b8-e6b60275cca7</atom:title>
		<app:collection href="http://cmis.alfresco.com/cmisatom/371554cd-ac06-40ba-98b8-e6b60275cca7/children?id=workspace%3A%2F%2FSpacesStore%2F87b2f129-3ad0-4a46-a6ea-05ecbfb54aa1">
			<cmisra:collectionType>root</cmisra:collectionType>
			<atom:title type="text">Root Collection</atom:title>
			<app:accept>application/atom+xml;type=entry</app:accept>
			<app:accept>application/cmisatom+xml</app:accept>
		</app:collection>
		<app:collection href="http://cmis.alfresco.com/cmisatom/371554cd-ac06-40ba-98b8-e6b60275cca7/types">
			<cmisra:collectionType>types</cmisra:collectionType>
			<atom:title type="text">Types Collection</atom:title>
			<app:accept>
			</app:accept>
		</app:collection>
		<app:collection href="http://cmis.alfresco.com/cmisatom/371554cd-ac06-40ba-98b8-e6b60275cca7/query">
			<cmisra:collectionType>query</cmisra:collectionType>
			<atom:title type="text">Query Collection</atom:title>
			<app:accept>application/cmisquery+xml</app:accept>
		</app:collection>
		<app:collection href="http://cmis.alfresco.com/cmisatom/371554cd-ac06-40ba-98b8-e6b60275cca7/checkedout">
			<cmisra:collectionType>checkedout</cmisra:collectionType>
			<atom:title type="text">Checked Out Collection</atom:title>
			<app:accept>application/cmisatom+xml</app:accept>
		</app:collection>
		<app:collection href="http://cmis.alfresco.com/cmisatom/371554cd-ac06-40ba-98b8-e6b60275cca7/unfiled">
			<cmisra:collectionType>unfiled</cmisra:collectionType>
			<atom:title type="text">Unfiled Collection</atom:title>
			<app:accept>application/cmisatom+xml</app:accept>
		</app:collection>
		<cmisra:repositoryInfo xmlns:ns3="http://docs.oasis-open.org/ns/cmis/messaging/200908/">
			<cmis:repositoryId>371554cd-ac06-40ba-98b8-e6b60275cca7</cmis:repositoryId>
			<cmis:repositoryName>Main Repository</cmis:repositoryName>
			<cmis:repositoryDescription>Main Repository</cmis:repositoryDescription>
			<cmis:vendorName>Alfresco</cmis:vendorName>
			<cmis:productName>Alfresco Repository (contentUrl=store://2011/4/20/15/11/aa15f2b9-60ad-40c6-8cc7-76eecbb0438c.bin|mimetype=application/octet-stream|size=752|encoding=|locale=en_GB_|id=28878)</cmis:productName>
			<cmis:productVersion>4.0.0 (b @build-number@)</cmis:productVersion>
			<cmis:rootFolderId>workspace://SpacesStore/87b2f129-3ad0-4a46-a6ea-05ecbfb54aa1</cmis:rootFolderId>
			<cmis:capabilities>
				<cmis:capabilityACL>manage</cmis:capabilityACL>
				<cmis:capabilityAllVersionsSearchable>false</cmis:capabilityAllVersionsSearchable>
			</cmis:capabilities>
			<cmis:aclCapability>
				<cmis:supportedPermissions>both</cmis:supportedPermissions>
				<cmis:permissions>
				<cmis:permission>{http://www.alfresco.org/model/content/1.0}cmobject.Coordinator</cmis:permission>
				<cmis:description>{http://www.alfresco.org/model/content/1.0}cmobject.Coordinator</cmis:description>
				</cmis:permissions>
			</cmis:aclCapability>
			<cmis:cmisVersionSupported>1.0</cmis:cmisVersionSupported>
		</cmisra:repositoryInfo>
		<atom:link rel="http://docs.oasis-open.org/ns/cmis/link/200908/typedescendants" href="http://cmis.alfresco.com/cmisatom/371554cd-ac06-40ba-98b8-e6b60275cca7/typedesc" type="application/atom+xml;type=feed" />
		<cmisra:uritemplate>
			<cmisra:template>http://cmis.alfresco.com/cmisatom/371554cd-ac06-40ba-98b8-e6b60275cca7/id?id={id}&amp;filter={filter}&amp;includeAllowableActions={includeAllowableActions}&amp;includeACL={includeACL}&amp;includePolicyIds={includePolicyIds}&amp;includeRelationships={includeRelationships}&amp;renditionFilter={renditionFilter}</cmisra:template>
			<cmisra:type>objectbyid</cmisra:type>
			<cmisra:mediatype>application/atom+xml;type=entry</cmisra:mediatype>
		</cmisra:uritemplate>
	</app:workspace>
</app:service>

To specify which REST route should be the endpoint, a @AtomPubEndpoint annotation should be put in the REST controller. So if someone request the endpoint with the Atom format and the annotation is present, a response similar to the example should be returned.

A Atom collection is simply a list of documents, so again a @AtomPubCollection annotation should be put in the REST controller. Another annotation, @AtomAcceptedMediaTypes should be added, if not present, every media type will be accepted.

When a collection is fetched (with a GET), it looks like this:

GET [http://localhost/wordpress/wp-app.php/posts]

HTTP/1.1 200 OK
Content-Length: 3182
Date: Sat, 07 Apr 2012 10:34:51 GMT
Server: Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.8 with Suhosin-Patch
X-Powered-By: PHP/5.3.8
X-Pingback: [http://localhost/wordpress/xmlrpc.php]
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Last-Modified: Sat, 07 Apr 2012 10:34:51 GMT
Cache-Control: no-cache, must-revalidate, max-age=0
Pragma: no-cache
Connection: close
Content-Disposition: attachment; filename=atom.xml
Content-Type: application/atom+xml

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xml:lang="en"  >
<id>[http://localhost/wordpress/wp-app.php/posts]</id>
<updated>2011-02-27T15:55:28Z</updated>
<title type="text">Move to WO\!</title>
<subtitle type="text">Just another WordPress site</subtitle>
<link rel="first" type="application/atom+xml" href="http://localhost/wordpress/wp-app.php/posts" />
<link rel="last" type="application/atom+xml" href="http://localhost/wordpress/wp-app.php/posts" />
<link rel="self" type="application/atom+xml" href="http://localhost/wordpress/wp-app.php/posts" />
<rights type="text">Copyright 2012</rights>
<generator uri="http://wordpress.org/" version="3.3.1">WordPress</generator>
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:app="http://www.w3.org/2007/app" xml:lang="en">
<id>[http://localhost/wordpress/?p=4]</id>
<title type="text">Un test</title>
<updated>2011-02-27T15:55:28Z</updated>
<published>2011-02-24T01:30:38Z</published>
<app:edited>2011-02-27T15:55:28Z</app:edited>
<app:control>
<app:draft>no</app:draft>
</app:control>
<author>
<name>admin</name>
</author>
<link href="http://localhost/wordpress/?p=4" />
<content type="html"><\!\[CDATA\[fgfgfd
&nbsp;\]\]></content>
<link rel="edit" href="http://localhost/wordpress/wp-app.php/post/4" />
<category scheme="http://localhost/wordpress" term="Une catégorie" />	<summary type="html"><\!\[CDATA\[\]\]></summary>
</entry>
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:app="http://www.w3.org/2007/app" xml:lang="en">
<id>[http://localhost/wordpress/?p=1]</id>
<title type="text">Hello world\!</title>
<updated>2011-02-24T01:22:13Z</updated>
<published>2011-02-24T01:22:13Z</published>
<app:edited>2011-02-24T01:22:13Z</app:edited>
<app:control>
<app:draft>no</app:draft>
</app:control>
<author>
<name>admin</name>
</author>
<link href="http://localhost/wordpress/?p=1" />
<content type="text">Welcome to WordPress. This is your first post. Edit or delete it, then start blogging\!</content>
<link rel="edit" href="http://localhost/wordpress/wp-app.php/post/1" />
<category scheme="http://localhost/wordpress" term="Uncategorized" />	<summary type="text">Welcome to WordPress. This is your first post. Edit or delete it, then start blogging\!</summary>
</entry>
</feed>

Creating a new post (a new entry):

POST /wordpress/wp-app.php/posts HTTP/1.1
Content-Length: 536
Content-Type: application/atom+xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<entry xmlns="http://www.w3.org/2005/Atom">
<title type="text"><\!\[CDATA[Test par AtomPub]\]></title>
<content type="html" xml:space="preserve"><\!\[CDATA[<p><strong>allo&#33;</strong></p>\||]\]></content>
<summary type="html" xml:space="preserve"><\!\[CDATA\[\]\]></summary>
<category term='Une catégorie'></category>
<app:control xmlns:app='http://www.w3.org/2007/app'>
<app:draft>no</app:draft>
</app:control>
<generator url="http://www.red-sweater.com/marsedit/">MarsEdit</generator>
</entry>

HTTP/1.1 201 Created
Content-Length: 780
Date: Sat, 07 Apr 2012 10:47:50 GMT
Server: Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.8 with Suhosin-Patch
X-Powered-By: PHP/5.3.8
Content-Location: [http://localhost/wordpress/wp-app.php/post/12]
Location: [http://localhost/wordpress/wp-app.php/post/12]
Connection: close
Content-Type: application/atom+xml

<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:app="http://www.w3.org/2007/app" xml:lang="en">
<id>[http://localhost/wordpress/?p=10]</id>
<title type="text">Test par AtomPub</title>
<updated>2012-04-07T10:30:45Z</updated>
<published>2012-04-07T10:30:45Z</published>
<app:edited>2012-04-07T10:30:45Z</app:edited>
<app:control>
<app:draft>no</app:draft>
</app:control>
<author>
<name>admin</name>
</author>
<link href="http://localhost/wordpress/?p=10" />
<content type="xhtml"><div xmlns='http://www.w3.org/1999/xhtml'><p><strong>allo\!</strong></p></div></content>
<link rel="edit" href="http://localhost/wordpress/wp-app.php/post/10" />
<category scheme="http://localhost/wordpress" term="Une catégorie" />	<summary type="text">allo\!</summary>
</entry>

Fetching an entry:

GET [http://localhost/wordpress/wp-app.php/post/10]

HTTP/1.1 200 OK
Content-Length: 819
Date: Sat, 07 Apr 2012 10:49:13 GMT
Server: Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.8 with Suhosin-Patch
X-Powered-By: PHP/5.3.8
Connection: close
Content-Disposition: attachment; filename=atom.xml
Content-Type: application/atom+xml

<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:app="http://www.w3.org/2007/app" xml:lang="en">
<id>[http://localhost/wordpress/?p=10]</id>
<title type="text">Test par AtomPub</title>
<updated>2012-04-07T10:30:45Z</updated>
<published>2012-04-07T10:30:45Z</published>
<app:edited>2012-04-07T10:30:45Z</app:edited>
<app:control>
<app:draft>no</app:draft>
</app:control>
<author>
<name>admin</name>
</author>
<link href="http://localhost/wordpress/?p=10" />
<content type="xhtml"><div xmlns='http://www.w3.org/1999/xhtml'><p><strong>allo\!</strong></p></div></content>
<link rel="edit" href="http://localhost/wordpress/wp-app.php/post/10" />
<category scheme="http://localhost/wordpress" term="Une catégorie" />	<summary type="text">allo\!</summary>
</entry>
 
  • No labels