A RESTful Approach

The Atom Feeds and Entries themselves are simply a format. To complete the Atom Publishing Protocol there must be a transfer protocol. That missing link is the Hypertext Transfer Protocol (HTTP). This approach, simply using HTTP without any extensions, is referred to as RESTful. (This is a simplification)

The basis behind using HTTP is quite simple. The protocol is sufficient for the operations that Atom Publishing Protocol needs to perform. HTTP is heavily used, quite lightweight, and is convenient for the Atom's XML format (which is plain text). The key portions for an Atom Request are the URI, the HTTP Request Method, the Content Type being Sent, and the Return Type. Here is a chart to make it a little easier to digest:


HTTP RequestSending TypeReturn Type
POST Atom Entry Atom Entry
Check HTTP Location Header
PUT Atom Entry HTTP 200 OK
DELETE - HTTP 200 OK
GET - Atom Feed or Atom Entry

This table is quite succinct but may require some initial explaining. Lets run through each of these items individually. You may hear the acronym CRUD, meaning Create, Read, Update, and Delete.


POST - Create a Resource

If you would like to add an entry to a blog, add a comment to an article, or submit an image to a photo gallery, these are all actions involving adding a resource to a collection. Using the Atom Publishing Protocol you would first wrap the data that you want to add into an Atom Entry. As is the case with any Atom Request there will be a specific URI (in most cases on the web this will just be a URL) that handles creating resources. These URIs are discovered via the Atom Service Documents, Atom Feeds, and Atom Entries in the href attributes scattered throughout <link>, <collection>, and even other Atom tags. In the case of creation you will most likely be looking for a collection to add to.

Once you have both the URL and the Atom Entry you can then submit a POST HTTP Request, sending the Atom Entry as your data to that URL. The Atom Publishing Protocol (AtomPub for short) will confirm a successful creation by returning to you the Atom Entry that it has created and stored in its system and most importantly in the server's response HTTP Headers the Location header will contain the URI for the newly created resource. Lets Recap:

  1. Represent your addition as an Atom Entry

  2. POST to the Collection URI

  3. 201 Created will be the HTTP Response Code

  4. Response Header "Location: New Member URI"

Lets give a simple example. Here we post a very short blog article, encapsulated in the following Atom Entry to the example.org/myblog/entries/ URL:

POST /myblog/entries HTTP/1.1
Host: example.org
Authorization: Basic ZGFmZnk6c2VjZXJldA==
Content-Type: application/atom+xml;type=entry
Content-Length: nnn
Slug: First Post

<?xml version="1.0" ?>
<entry xmlns="http://www.w3.org/2005/Atom">
  <title>Atom-Powered Robots Run Amok</title>
  <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
  <updated>2007-02-123T17:09:02Z</updated>
  <author><name>Captain Lansing</name></author>
  <content>It's something moving... solid metal</content>
</entry>

And here was the Server's Response, a 201 Created Status, a Location Header pointing to the URL for the newly created resource, and of course the Atom Entry representation of the newly created resource:

HTTP/1.1 201 Created
Date: Fri, 23 Feb 2007 21:17:11 GMT
Content-Length: nnn
Content-Type: application/atom+xml;type=entry
Location: http://example.org/edit/first-post.atom
Content-Location: http://example.org/edit/first-post.atom
ETag: "e180ee84f0671b1"

<?xml version="1.0" ?>
<entry xmlns="http://www.w3.org/2005/Atom">
  <title>Atom-Powered Robots Run Amok</title>
  <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
  <updated>2007-02-123T17:09:02Z</updated>
  <author><name>Captain Lansing</name></author>
  <content>It's something moving... solid metal</content>
</entry>
Media Resources

Now in the case of a media resource such as an image or video this is only slightly different. You will still need to submit an Atom Entry to a URI providing the metadata about the media resource. This metadata Entry is called the Media Link Entry. Following the creation of the Media Link Entry there will be a <link rel="edit-media" ...> which holds another URI. This is the URI that you can use to then POST the raw binary data of the media to, thus creating a Media Resource on the server if you receive a successful response from the server. Remember, the server only accepts certain media types. These acceptable types should be listed in separate <accept> tags in the Service Document's <collection> element.


GET - Pull Feeds or Individual Entries

The most common request is most certainly just pulling an Atom Feed or specific Atom Entry from the server. This transaction is very simple, just locate the URI for the collection or individual resource, and submit a GET request to that URI. Again, you will want to look at the href attribute inside a Service Document's <collection> tag for Feed URIs and inside <link> tags most often for individual Entry URIs. Here is a simple example for getting the full details of the blog post we just created.

GET /edit/first-post.atom HTTP/1.1
Host: example.org
Authorization: Basic ZGFmZnk6c2VjZXJldA=="

And here is the expected Server's Response, a 200 OK Message with the Atom Entry attached:

HTTP/1.1 200 OK
Date: Fri, 7 Oct 2005 17:20:11 GMT
Content-Length: nnn
Content-Type: application/atom+xml;type=entry;charset="utf-8"
Location: http://example.org/edit/first-post.atom

<?xml version="1.0" ?>
<entry xmlns="http://www.w3.org/2005/Atom">
  <title>Atom-Powered Robots Run Amok</title>
  <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
  <updated>2007-02-123T17:09:02Z</updated>
  <author><name>Captain Lansing</name></author>
  <content>It's something moving... solid metal</content>
</entry>
PUT - Update a Resource

When you update a resource using the Atom Publishing protocol you are actually completely replacing the Atom Entry itself. This introduces one of the few problems in the Atom Publishing Protocol, a race condition when multiple sources try to update the same Entry at the same time. Whoever updates last will have their update saved. This is a rather unlikely occurrence but it is possible none the less.

Because of the requirement to replace the entire Entry it is recommended, and quite natural, to first GET the resource. Just like the previous example you will retrieve a fresh representation of the resource that you can modify and then send back to the server with a PUT request. Using the PUT request is exactly like the POST request but this time it is to the member's edit URI instead of the collection URI.

PUT /edit/first-post.atom HTTP/1.1
Host: example.org
Authorization: Basic ZGFmZnk6c2VjZXJldA=="

<?xml version="1.0" ?>
<entry xmlns="http://www.w3.org/2005/Atom">
  <title>Atom-Powered Robots Go Crazy</title>
  <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
  <updated>2008-02-123T17:09:02Z</updated>
  <author><name>Captain Lansing</name></author>
  <content>Some Robots are Crazy!</content>
</entry>

I marked my changes in green. I updated the title, content, and the updated timestamp (even though the server might ignore my value and replace it instead with its own timestamp). The server will respond with a 200 OK message if the update was successful:

HTTP/1.1 200 OK
Date: Fri, 8 Oct 2006 17:17:11 GMT
DELETE - Remove a Resource

To delete a resource you would just send a DELETE request to the member's URI. This is the same URI that you would use a GET request to see the resources Atom Entry representation.

DELETE /edit/first-post.atom HTTP/1.1
Host: example.org
Authorization: Basic ZGFmZnk6c2VjZXJldA=="

On a successful deletion the server will respond with a 200 OK Message:

HTTP/1.1 200 OK
Date: Sat, 24 Feb 2007 13:17:11 GMT