Now blogging at diego's weblog. See you over there!

blogging APIs: a mini how-to


There were a lot of good comments to my previous review of blogging APIs. I was working today on this howto and I think it will make a nice follow-up. Writing this is as much a learning experience for me as it is sharing what I've learned, so I'm sure I will add to it over time. And as usual, comments and corrections are welcome.

One thing that makes weblog APIs hard to "grasp" is that, while the specifications are complete, there are few examples, and it's not clear outright how to make a call for the various things one might do with the API (Although the specs usually do provide examples). Sam Ruby suggested using a "test case" and comparing how the request would be made for it using the different APIs. I was going to give different examples but Sam's idea is better, so I've reworked the doc. And here it is! (posting split in two to keep the main body of it off the main page)

the tools: a short intro to XML-RPC

The most basic tool necessary to use a blogging API is an HTTP library. Blogging APIs use XML-RPC which runs on top of HTTP, receiving a "call" in well-defined XML format and receiving the response using the same format. (The XML-RPC spec is here). In XML-RPC, the I/O on the function call is done through the I/O of the HTTP call, with the XML passed in the body of the page request, and the response in the "page" that the URL has returned. Because of this, XML-RPC calls tend to be stateless, but they don't need to be.

If, for example, you are using Java, you might be tempted to use the XML-RPC package from Apache. But as far as I can see (although of course I might be wrong, having overlooked something) the Apache XML-RPC package for Java doesn't allow the use of XML-RPC , just "one-dimensional" lists of parameters. The point is that whatever XML-RPC package you choose, you'll end up having to debug by looking at the request you're making, and the response you're receiving. If you don't have an XML Parser/Generator available (there are many) you will end up having to look at raw XML code. Which isn't so terrible really. :) For simplicity, I will look at how calls are made (and responses received) using the full XML request/response. Having an XML or even XML-RPC tool available "only" means that you won't have to debug XML parse/generate code.

So keeping on with this, the basic parameters that the HTTP call needs are:

  • Content-Length: the length of the XML-RPC request in bytes.
  • Content-Type: text/xml
And that's it! After that the body of the request should contain the XML for the request (so the connection has to be set up for input as well as output).

the test case

As a test case, let's consider the following: you want to create a post, assigning it to a category.

The post will have the following content:

Title: sunny days
Text: <a href="sunny.jpg">I don't like sunny days. Do you?
Picture: sunny.jpg (A picture that is included in the post)
Category: personal

This of course assumes that there is a category "personal" on your weblog. :)

preparations

Before we begin, the list of blogging APIs can be found in the review, but here they are for completeness:

My rationale for going with both Blogger and MetaWeblog only is explained in the review, and I've added the MovableType implementation since it is very close to using the MetaWeblog API for the same effect.

Posting to weblog software is usually easy: the major tools allow to post to your weblog without special modifications. Blogger, however, does require that you obtain an "application ID" before posting (it's free), which then has to be included in the request. As far as I know, other applications such as MovableType or Radio that implement the Blogger API simply ignore this value, so for testing with those you won't need it.

MovableType requires certain modules for remote posting to be activated. Since those modules are optional, you need to make sure they're installed before proceeding. The MovableType installation documentation has information on how to add those modules. It's about 5 minutes work.

making the call

So, once everything is set up, how is the call made to, first, create the post? I will show how the call is made for the Blogger API, the MetaWeblog API, and the MovableType API. Although the MT API is only implemented by MT, there's no other way to set the category from the post, so we'll have to use those extensions. I will give examples for the three best-known weblogging tools: Blogger, Radio and MovableType. Blogger implements the Blogger API only, Radio and MovableType implement both the Blogger API and the MetaWeblog API, and MT adds its own extensions as well.

The APIs are stateless; that is, they require validation on every request. Making them stateless is nice, but I think it would be better if the password was at least going encrypted over the wire--for example, with a one-way MD5 hash. But that's a subject for a different post. ;)

General note: the parameter "yourBlogID" is the weblog ID, and it is internal to the system. To obtain the blogID, you need to make a "blogger.getUsersBlogs" call and choose it from there (both the name for the blog and the id are returned). Since all tools implement the Blogger API, this call can be used across systems.

Regarding the requests: I had to do some heavy editing to make it appear properly in HTML, please let me know if there's a typo somewhere.

Posting to Blogger

The Blogger API has no concept of categories or titles, so the end result will be less complete than for Radio or MovableType. Additionally, Blogger doesn't as yet allow uploading of images, so we'll have to strip the image out of the content. Here is the request:

<?xml version="1.0" ?>
<methodCall>
 <methodName>blogger.newPost</methodName>
  <params>
   <param><value>bloggerAppKey</value></param>
   <param><value>yourBlogID</value></param>
   <param><value>yourUserName</value></param>
   <param><value>yourPassword</value></param>
   <param><value>sunny days &lt;BR&gt;&lt;BR&gt; I don't like sunny days. Do you?</value></param>
   <param><value>true</value></param>
 </params>
</methodCall>


Note: the "<BR><BR>" text is added to give the impression that "sunny days" is the title of the post. The final parameter "true" which indicates that we want this posting to be published right away. Also, note that the HTML tags in the main body "<BR>" have to be converted to "&lt;BR&gt;" to avoid confusing the XML parser.

Posting to Radio and MovableType

Most of the following code applies to both Radio and MovableType. There's a final step for dealing with categories in MovableType. I'll go over that after this main example.

Since the posting contains an image, we need to upload the image first and then use the URL returned by the blogging software in the posting--the reference "sunny.jpg" will work locally, but not remotely.

So, to upload the image we need to use the following call

<?xml version="1.0" ?>
<methodCall>
 <methodName>metaWeblog.newMediaObject</methodName>
  <params>
   <param><value>yourBlogID</value></param>
   <param><value>yourUserName</value></param>
   <param><value>yourPassword</value></param>
   <param>
   <value>
    <struct>
    <member>
     <name>name</name>
     <value>sunny.jpg</value>
    </member>
    <member>
     <name>bits</name>
     <value>[the contents of the file in Base 64 encoding]</value>
    </member>
    <member>
     <name>type</name>
     <value>image/jpeg</value>
    </member>
    </struct>
   </value>
  </param>
 </params>
</methodCall>

This call returns the URL through which the image can now be accessed. Note that the "type" value is currently (as of version 2.63) ignored by MovableType. The type is the standard MIME type of the file that's being uploaded, for binary files (such as a word processor document) it would be typical to use the "application/octet-stream" encoding.

Now that the image is uploaded, we can create the post.

<?xml version=\"1.0\" ?>
<methodCall>
 <methodName>metaWeblog.newPost</methodName>
  <params>
   <param><value>yourBlogID</value></param>
   <param><value>yourUserName</value></param>
   <param><value>yourPassword</value></param>
   <param>
    <value>
    <struct>
     <member>
      <name>title</name>
      <value>sunny days</value>
     </member>
     <member>
      <name>description</name>
      <value>&lt;a href="[url obtained through call to metaWeblog.newMediaObject"&gt;I really like sunny days.</value>
     </member>
     <member>
      <name>categories</name>
      <value><array><data>
       <value>personal</value>
      </data></array></value>
     </member>
    </struct>
    </value>
   </param>
   <param><value>true</value></param>
 </params>
</methodCall>

This call returns the "postID" of the post, which can later be used to edit it, as we'll see now.

The one difference between the Radio call and the MT call is the "categories" parameter--which MT doesn't support. MT supports only the setting of the title, description, and date created for the post, as well as a few MT extensions. However, there's a way in MT of setting a post's category, after it was published, with the following call:

<?xml version=\"1.0\" ?>
<methodCall>
 <methodName>mt.setPostCategories</methodName>
 <params>
  <param><value>postID</value></param>
  <param><value>yourUserName</value></param>
  <param><value>yourPassword</value></param>
  <param>
  <value>
   <array><data>
   </struct>
   <member>
   <name>categoryID</name>
   <value>1</value>
   <name>isPrimary</name>
   <value>true</value>
   </member>
  </struct></value>
  </data></array>
  </param>
  </params>
  </methodCall>

The postID used is the postID received from the previous call. Note here that the category used is a "categoryID" rather than the name. Radio will ignore the category if it doesn't exist. To obtain the categoryIDs in MovableType, you can call the "mt.getCategoryList" function. Radio uses a MetaWeblog API call to return the categories, "metaWeblog.getCategories", which is the only function in the MetaWeblog API that MT doesn't implement (presumably because it already includes a method for that).

conclusions
As we could see, both Radio and MovableType support more complete functionality than blogger, although MT requires an additional step. The Blogger API 2.0, not yet deployed, provides more functionality but it still doesn't provide a way to upload objects, such as images, but since it appears that they are actively working on it, that might change.

Finally: as I've said before (and others, such as Marc, have expressed similar views), having a single API to support would be a godsend. Right now, if a tool has to support all three applications there's no way except to create three different implementations, as this example shows, even for something as simple as creating a post with categories and one image. Hopefully this will change in the future! As Dave was pointing out, the new Blogger API will not be backward compatible, and the document confirms that. Since so many things are going to break anyway, it would be worthwhile, IMO, to use this opportunity to get all the APIs to agree. Of course, this would mean other applications would have to update as well, but this would be a good time to make the change and create a common base for future development.

Categories: technology
Posted by diego on May 6 2003 at 12:16 AM

Copyright © Diego Doval 2002-2011.
Powered by
Movable Type 4.37