Sign In/My Account | View Cart  
advertisement


Listen Print Discuss

The Atom API
by Mark Pilgrim | Pages: 1, 2

API Discovery

Previous weblog services had no concept of API discovery. They left it up to the end user to provide the exact API URL (http://example.com/mt/mt-xmlrpc.cgi). Some servers implemented undocumented functions like deletePost, and even knowing the type of software running on the other end was not enough because different versions of the same software supported extra functionality over time. Client software had to guess what functionality was provided and what extensions were supported

The Atom API assumes only that the end user knows her home page. It relies on a link tag in the head element of the home page that points to an Atom introspection file. The introspection file, in turn, lists the supported functions and extensions, as well as the URI associated with each function.

Here is an example of a home page with Atom API auto-discovery:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>My Weblog</title>
<link rel="service.edit" type="application/x.atom+xml" 
  href="/myblog/atom.cgi/introspection" title="Atom API" />
</head>
<body>
...
</body>
</html>

If this resource is http://www.example.com/, it says that the Atom introspection file is the http://www.example.com/myblog/atom.cgi/introspection resource. Note that this is actually routing through a CGI script, as are all the other examples I'll list here. Nothing in Atom requires this, but when I wrote a server prototype of the Atom API, I made a point to route everything through a single CGI script because there was some debate about whether this was even possible. It could easily be a set of CGI scripts, or JSPs, ASP, PHP, or any other language.

The introspection file then lists the supported function and extensions in a simple, well-defined XML format. There are a number of functions defined in the core Atom API, and vendors can extend the introspection file with XML namespaces to point to their own extension methods. A core Atom API introspection file (like http://www.example.com/myblog/atom.cgi/introspection) might look like this:

GET /myblog/atom.cgi/introspection HTTP/1.1
Host: example.com
HTTP/1.1 200 OK
Content-Type: application/x.atom+xml

<?xml version="1.0" encoding="utf-8"?>
<introspection xmlns="http://purl.org/atom/ns#" > 
  <search-entries>http://example.com/myblog/atom.cgi/search</search-entries>
  <create-entry>http://example.com/myblog/atom.cgi/edit</create-entry>
  <edit-template>http://example.com/atom.cgi/templates</edit-template>
  <user-prefs>http://example.com/myblog/atom.cgi/prefs</user-prefs>
  <categories>http://example.com/atom.cgi/categories</categories>
</introspection>

Retrieving Entries

If you're writing client software to manage a weblog, the first thing you'll probably want to do after getting the introspection file is get a list of existing entries. The introspection file lists the address for searching entries in <search-entries>. The client can add query string parameters such as atom-last to find recent entries. More complex examples are defined in the Atom API spec draft.

Here's how you would get a list of recent entries:

GET /myblog/atom.cgi/search?atom-last=20 HTTP/1.1
Host: example.com
HTTP/1.1 200 OK
Content-Type: application/x.atom+xml

<search-results xmlns="http://purl.org/atom/ns#" > 
  <entry>
    <title>My Second Post</title>
    <id>http://example.com/atom.cgi/edit/2</id>
  </entry>
  <entry>
    <title>My First Post</title>
    <id>http://example.com/atom.cgi/edit/1</id>
  </entry>
</search-results>

The remainder of the Atom API follows the principles of REST. New entries are created using HTTP POST to post an Atom entry to the create-entry address specified in the introspection file. Retrieving an entry is accomplished by doing an HTTP GET on the entry's URI, which is returned after creating new entry or in search results. Editing an entry is accomplished by doing an HTTP PUT on the entry's URI; deleting an entry is an HTTP DELETE on the entry's URI.

When I say "the entry's URI", remember that that's implementation-specific. These examples route everything through a single script (atom.cgi), just to prove that you can do that. Of course if you're implementing the Atom API on your own server, you don't have to do that; you could use JSP, or PHP, or Perl, or anything that can handle the four basic HTTP operations (GET, POST, PUT, DELETE). The introspection file rules all; it's the client's guide to the structure of the server's Atom web services.

As I said, retrieving an existing entry is as simple as an HTTP GET of the entry's URI. The search results told us that the first post had a URI of http://example.com/atom.cgi/edit/1, so let's get that:

GET /myblog/atom.cgi/edit/1 HTTP/1.1
Host: example.com
HTTP/1.1 200 OK
Content-Type: application/x.atom+xml

<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://purl.org/atom/ns#">
  <title>My First Entry</title> 
  <summary>My First Entry Excerpt (generally plaintext)</summary> 
  <author> 
    <name>Bob B. Bobbington</name> 
    <email>bob@example.com</email>
    <url>http://homepage.example.com/</url>
  </author> 
  <issued>2003-10-15T02:29:29</issued> 
  <created>2003-10-15T04:10:58Z</created> 
  <modified>2003-10-15T04:22:03Z</modified> 
  <link>http://example.com/myblog/archives/2003/11/19/My_First_Entry.html</link>
  <id>urn:example-com:myblog:1</id>
  <content type="application/xhtml+xml" xml:lang="en"> 
    <div xmlns="http://www.w3.org/1999/xhtml">
      <p>Hello, <em>weblog</em> world!</p>
      <p>This is my first post <strong>ever</strong>!</p>
    </div>
    </content>  
</entry>

Lots of information here: the entry has a title, an excerpt or summary, and an author who has a name, email address, and URL of his own. The entry has a created date and a modified date (usually server-generated), and an "issued" date (which is a date that the author would like to give to this entry, separate from when he actually posted it). The entry is viewable at a specific link, has an internal ID (a URN), and finally has some XHTML content.

The Atom content model is probably worth a whole article by itself, but for the moment let me just handwave and say that it can handle more than just XHTML. Any MIME type can be expressed (specify it in the @type attribute), and non-XML content (such as HTML or plain text) is simply escaped or put in a CDATA block, with a mode="escaped" attribute on the content element. It can even handle binary content (such as an image) by specifying @mode="base64" and including a base64-encoded representation of the data.

Creating, Editing, and Deleting entries

Posting a new entry is virtually symmetrical. To create a new entry, do an HTTP POST on the URI create-entries address specified in the introspection file. The body of the HTTP POST should be an entry, in the same Atom format as you got back from the server on retrieve:

POST /myblog/atom.cgi/edit HTTP/1.1
Host: example.com
Content-Type: application/x.atom+xml

<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://purl.org/atom/ns#">
  <title>My Entry Title</title> 
  <created>2003-11-17T12:29:29Z</created> 
  <content type="application/xhtml+xml" xml:lang="en"> 
    <div xmlns="http://www.w3.org/1999/xhtml">
      <p>Hello, <em>weblog</em> world!</p>
      <p>This is my third post <strong>ever</strong>!</p>
    </div>
  </content>  
</entry>

The server responds with an HTTP status code 201 "Created" and gives the entry's edit URI in the HTTP Location: header.

HTTP/1.1 201 Created
Location: http://example.com/myblog/atom.cgi/edit/3

Note that since we're using straight XML (rather than a serialization of XML over RPC over XML), extensibility is handled by XML namespaces. For example, Movable Type allows individual entries to allow comments or not. This functionality is not built into the Atom API, but Six Apart could easily extend the API like this:

POST /myblog/atom.cgi HTTP/1.1
Host: example.com
Content-Type: application/x.atom+xml

<?xml version="1.0" encoding="utf-8"?>
<entry
  xmlns="http://purl.org/atom/ns#"
  xmlns:mt="http://www.movabletype.org/atom/ns#">

  <title>My Entry Title</title> 
  <created>2003-11-17T12:29:29Z</created>
  <mt:allowComments>1</mt:allowComments>
  <content type="application/xhtml+xml" xml:lang="en"> 
    <div xmlns="http://www.w3.org/1999/xhtml">
      <p>Hello, <em>weblog</em> world!</p>
      <p>This is my first post <strong>ever</strong>!</p>
    </div>
  </content>  
</entry>

Modifying an existing entry is almost the same as creating one. You do an HTTP PUT on the entry's URI (as returned in the Location: header after creating it or in the id element in the search results), with the entry in the body of the HTTP message, in the same Atom XML format we've seen in other method calls:

PUT /myblog/atom.cgi/edit/1 HTTP/1.1
Host: example.com
Content-Type: application/x.atom+xml

<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://purl.org/atom/ns#">
  <title>My First Entry</title> 
  <summary>My First Entry Excerpt (generally plaintext)</summary> 
  <author> 
    <name>Bob B. Bobbington</name> 
    <email>bob@example.com</email>
    <url>http://homepage.example.com/</url>
  </author> 
  <issued>2003-10-15T02:29:29</issued> 
  <created>2003-10-15T04:10:58Z</created> 
  <modified>2003-10-15T04:22:03Z</modified> 
  <link>http://example.com/myblog/archives/2003/11/19/My_First_Entry.html</link>
  <id>urn:example-com:myblog:1</id>
  <content type="application/xhtml+xml" xml:lang="en"> 
    <div xmlns="http://www.w3.org/1999/xhtml">
      <p>Hello, <em>weblog</em> world!</p>
      <p>This is my first post <strong>ever</strong>!</p>
    </div>
    </content>  
</entry>

On success the server responds with an HTTP status code 205 "Reset Content".

HTTP/1.1 205 Reset Content

Deleting an entry is even simpler:

DELETE /myblog/atom.cgi/edit/3 HTTP/1.1
Host: example.com
HTTP/1.1 200 OK

Further reading

More Dive Into XML Columns

Identifying Atom

XML on the Web Has Failed

The Atom Link Model

Normalizing Syndicated Feed Content

Atom Authentication

We have, in some sense, come full circle. The original LiveJournal API was REST-based, although it was limited to the simple name-value pairs for input and output. After that, weblogging APIs went down a path of RPC-style services, until that became completely unmanageable. And now we're back to a document-centric, REST-inspired service again.

The Atom API has several other methods beyond add, edit, delete, retrieve, search. It can be used for posting comments on entries, managing users and user preferences, managing categories, managing site templates; eventually it will be usable for everything you can do manually with your weblog through your server's browser-based interface. You can read the latest draft for yourself or download sample source code that implements the API in Python, Perl, PHP, or Java.

"But, but, but," I hear you cry, "what about passwords sent in the clear?" Ah, yes. Atom authentication deserves its own article, and I promise to tackle it, if not next month then the month after. I can promise that it does not involve sending plain text passwords in the clear.


Comment on this articleWhat do you think about the Atom API? Share your views in our forum.
(* You must be a
member of XML.com to use this feature.)
Comment on this Article


Titles Only Titles Only Newest First
  • carpet and upholstery cleaning services 1-818-386-1022
    2008-09-26 18:11:20 0 [Reply]

    Our mission is to provide the very best carpet and upholstery cleaning services call 1-818-386-1022 to residential and commercial clients throughout Los Angeles, San Fernando Valley, CA . Clean Health Carpet Care is dedicated to meeting the needs of our clients through innovative cleaning technologies, 5-star customer service and industry expertise. Our certified technicians specialize in deep cleaning your carpets and rugs, leaving them looking great and germ free. Free Pick Up and Delivery of area rugs is available upon request. Cleaning of your area rugs can be done in our specialized facility, at your home or in your location. Our specialties: Spot and Stain Removal Pet Stain and Odor Removal Wall to Wall Carpets Schotchguard © Sanitizing and Disinfecting Oriental Rug Cleaning Specialty and Delicate Rugs Water Damage and Restoration. Upholstered furniture has a more varied range of materials and manufacturing methods than carpet. Our knowledgeable technicians can identify the fabric type of each upholstered piece and what cleaning methods will give your upholstery the best, safest and longest lasting results. Sofas Recliners Dinning chairs Love Seats Arm Chairs Leather furniture professional technicians are specially trained in the care of all fabric types, even the most delicate, so you can feel comfortable in knowing they’ll choose the proper upholstery cleaning solution for your furniture. And using specially designed tools to gently clean folds and crevices, they’ll ensure the entire piece is entirely clean

  • SOAP?
    2003-10-17 22:54:24 Terris Linenbach [Reply]

    What's the reason for using http/REST instead of SOAP?

  • Finally, it's clear why we have Atom
    2003-10-16 19:55:05 Steve Kirks [Reply]

    Mark:


    I know you and others have taken a dumptruck full of flack about Atom, but now I get it. No, I'm not a programmer, but I understand the syntax and the frustration of previous RPC-type interfaces.


    It would be easy to add this to a program for compatibility issues. Atom seems like a great solution to a problem I didn't know existed.


    As far as the debate is concerned, I think that some may be missing the compliment paid. If the LiveJournal/Blogger/metaWeblog APIs were significant or important, their contributions would have been ignored during the Atom development process.


    Sometimes it's hard to see prior art if you are squinting through a frown.

  • Informative, But...
    2003-10-16 10:40:17 Don Park [Reply]

    "The Atom API was designed because the MetaWeblog API proved that RPC-based APIs were simply the wrong solution for this problem."


    Maybe right from Mark's pov but I don't think this is true for significant portion of Atom supporters.


    Also, PUT/DELETE discussion is still going on and consensus is marginally against use of PUT/DELETE last time I checked.

    • Informative, But...
      2003-10-16 11:56:00 Mike Davies [Reply]

      > Also, PUT/DELETE discussion is still going on
      > and consensus is marginally against use of
      > PUT/DELETE last time I checked.


      I see five independantly working implementations and a draft API document based on a REST approach, yet I see no implementations or drafts API of any other format. Certainly looks like the initiative is with the PUT/DELETE approach.




      • Informative, But...
        2003-10-16 14:33:13 Don Park [Reply]

        I don't think having several implementations of a PUT/DELETE-based spec is an indication of pro-PUT/DELETE sentiment by those implementors.


        The problem is that there is no deadline on these discussions meaning it remains inconclusive. Meanwhile spec is unchanged and implementations are being written.

  • Clarification of resources
    2003-10-16 09:13:02 David Czarnecki [Reply]

    I wanted to further clarify the resources at the end of the article. blojsom is a Java-based weblog software package that uses the Sandler toolkit to create and consume Atom. If you just want a Java toolkit for creating and consuming Atom, Sandler is for you. If you want to look at how the Atom API was integrated in a Java-based weblog software package, by all means, download blojsom and take a look at that portion of our API.

    • Clarification of resources
      2003-10-16 09:35:30 David Czarnecki [Reply]

      I forgot to mention this in my comment. Sandler can be found at http://sandler.sf.net. If the link to the Java toolkit in the article can be changed to point there, that would be great. Thanks.

  • ManilaRPC
    2003-10-15 18:48:42 Dave Winer [Reply]

    Mark left out ManilaRPC which probably predates all the protocols. Since his story hinges on everything having started with Live Journal this omission is pretty glaring. Also Mark knows about it, he did Python interface for ManilaRPC.


    The rest of the article is as biased as one would expect from a designer of the Atom API. As usual O'Reilly allows people to write supposedly objective articles without disclaiming conflicts of interest.

    • ManilaRPC
      2003-10-16 09:38:14 Kendall Clark [Reply]

      For the record, the first thing XML.com published about Atom, before it was called Atom, was a (very opinionated) column I did in which I criticized some aspects of Atom. XML.com has not given the Atom effort a free pass by any stretch. Any suggestion to the contrary is simply wrong.


      >Since his story hinges on everything having >started with Live Journal this omission is pretty >glaring.


      No, not really. The piece doesn't in any way "hinge" on starting with Live Journal. That's where Pilgrim started, but so what? The current Userland contributions to this area were well and fairly reviewed in the piece. I suspect that the criticisms Pilgrim offered of all the things which preceded Atom were points that have been discussed in various communities endlessly. The column very nicely summarizes these issues in one place, but that's hardly the meat of the column.


      >Also Mark knows about it, he did Python interface >for ManilaRPC.


      Right, which suggests that he may probably had a good reason to leave it out, focusing on the Metaweblog API instead. There are any number of good reasons why it's a sensible thing to leave out.


      It seems to me that in order to sustain this claim -- which is itself quite unfriendly and hostile -- of bias, it has to be shown that there are only biased reasons for not discussing Manila RPC, and, further, that Pilgrim was motivated by these biased reasons. That's an awfully big burden. I'm not going to hold my breath.


      >The rest of the article is as biased as one would >expect from a designer of the Atom API.


      Actually, Pilgrim has implemented this API and been mostly involved with the Atom serialization format -- well, if his own reportage of his involvement is to be trusted, and I don't see any reason that it shouldn't be.


      >As usual O'Reilly allows people to write >supposedly objective articles without disclaiming >conflicts of interest.


      But that's what you are for, Dave! You are always "disclaiming our conflicts of interest" for us. :>


      I should state my own so-called "conflicts of interest": O'Reilly pays me, together with Edd Dumbill, to find and publish technically interesting content. I asked Mark Pilgrim to be an XML.com columnist, and I've edited all of his XML.com columns, including this one. I can't see any mistatements of fact or analysis in it, or I would have corrected them.


      But, wait, it gets worse! Mark and I have literally conspired together to publish critical analyses of XML-related things, including the Atom stuff. Just last night at dinner we deepened our conspiracy: I asked Mark if he'd be interested in working on some new areas in his future columns, and together we conspired to bring a new columnist to XML.com, about which more in coming weeks.


      So, you see, there is a conspiracy, the goal of which is to publish interesting material, based on objective analysis of technical merit, at XML.com.


      If that is the charge, we are *totally* guilty.




      • ManilaRPC
        2003-10-16 15:31:30 Matthew Haughey [Reply]

        >Just last night at dinner we deepened our conspiracy


        Waitaminute...you guys had dinner to discuss XML issues and I wasn't invited!?!?!

    • ManilaRPC
      2003-10-16 03:57:31 Edd Dumbill [Reply]

      Dave,


      Whatever gave you the idea articles were objective? Especially with columnists I encourage the expression of opinions in order to further debate and discussion.


      However, I also very much welcome correction to factual errors, and I'm glad you've taken the time to provide your feedback.


      -- Edd


      • ManilaRPC
        2003-10-16 05:00:30 Dave Winer [Reply]

        As a reader I want to know what conflicts of interest authors have. That way I know how much of what I'm reading is an ad, and how much of it is disinterested opinion. Anyway thanks for the data, I'm not going to tell you how to run your pub, but I have less respect for it now, and I'll take it less seriously.

        • Interests
          2003-10-20 05:26:03 Danny Ayers [Reply]

          The Atom project is open to all, so everyone that contributes could be said to be one of its developers.


          I note several contributions on the atom-syntax mailing list and even a page on the Wiki for a certain Dave Winer (http://www.intertwingly.net/wiki/pie/DaveWiner). If this is the same person as is posting here, perhaps they'd like to declare an interest too...


          btw, Mark - great piece.


        • ManilaRPC
          2003-10-16 07:55:23 Yoz Grahame [Reply]

          As a reader of both the piece and your comment, I'd like to know if you have any criticisms of the piece beyond accusations of bias. Sure, Mark states negative opinions of the MetaWeblog API, but he backs those up with clearly-stated reasons and facts.


          All you've said in response is that it's unfair that he doesn't mention that he's an Atom API developer, despite the fact that it's clearly an advocacy piece. Oh, and that he's a ManilaRPC developer, so he obviously knows what he's talking about.


          I don't care about political squabbles. I want to know which API I should be developing for, and Mark has made a an informative and convincing case for Atom, based entirely on its technical merits as compared to the other APIs in the field. If you can make arguments against the technical analyses in the piece without dragging politics into them, please do so. Otherwise, I'll assume you have none.

        • ManilaRPC
          2003-10-16 07:46:08 Adam Backstrom [Reply]

          Dave,


          As Chairman and Founder of UserLand Software (publisher of Manila), you should have noted your conflict of interest at the beginning of your comment. To supply a seemingly objective comment without this disclaimer is a pretty glaring omission.