Mar 07

Versatile RESTful APIs Beyond XML

An article I wrote has just been published over at InfoQ. It’s called Versatile RESTful APIs Beyond XML and shows how easy it can be to extend Rails’ RESTful behaviour to input and output resources not only as XML but also as JSON and Microformatted HTML.

The article builds on some posts on this blog, such as Intercepting Microformats In Rails Input, but offers a bit more context. The timing of the article fits nicely with a post on the microformats-rest list about Rails, REST and microformats, so hopefully we’ll see more discussion of these concepts over the coming weeks.

Feb 07

Relax over REST

Mark Nottingham has a good post running through a few topics on which people get needlessly caught when designing RESTful applications. If you’re new to working on RESTful application design (as many rails developers are) it’s worth checking out to save yourself needless anguish.

Thankfully for Rails developers at least some of the issues he identifies will be a little simpler than they might be for people designing systems from scratch. In particular, while there are a few URL design choices (numeric IDs, other parameters, or a hybrid? nested vs. flat?) the conventions are good and changing isn’t all that hard.

And while some sort of schema definition is important to ensure that server and client can be sure they’re speaking the same language, for those using tools like ActiveResource which take full advantage of dynamic languages, there’s a little more flexibility than there may have been before.

Jan 07

XML::Mapping and text nodes with attributes

While working on an API interface I’ve been playing around with XML::Mapping, an XML-to-object wrapper for ruby. The main reason to use it is that it allows me to easily build an interface similar to that used in Cody Fauser’s Ebay API client which will also be used in the same application.

Generally I’ve been very happy with the library, though at some point it would be nice to have a class generator which will take the XSD file and write most of the code for me, but scour the documentation as I may I couldn’t find an easy way to add attributes to a standard text-holding node. It’s easy enough to get:

  <person id="123">
	<name>First Person</name>

I couldn’t find a way to get:

  <person id="123">First Person</person>

without resorting to xpath wrangling.

Thankfully the library allows you to define your own node types, so once I added

module XML
  module Mapping
    class TextNodeWithAttributes < SingleAttributeNode

      def initialize_impl(path)
        @path = XML::XXPath.new(path)

      def extract_attr_value(xml)
        default_when_xpath_err{ @path.first(xml).text }

      def set_attr_value(xml, values)
        @path.first(xml, :ensure_created=>true).text = values.delete(:value)
        @path.first(xml, :ensure_created=>true).add_attributes(values) unless values.empty?

to my code and then included it with

XML::Mapping.add_node_class XML::Mapping::TextNodeWithAttributes

I could specify the above with the class:

module MyNamespace
  class Company
    text_node_with_attributes :person, 'person'

and create it with

MyNamespace::Company.new(:person => {:value => 'My Person', 'id' => '123'})

Aug 06

Namespaces, attributes and content in rxml

Rails’ RXML templates (powered by Builder) are a great way to generate various different types of XML output from your application, but the documentation could be lacking. I’ve been working with namespaced content for a while but I’ve spent quite a while today trying to work out how to add an element in an explicit namespace, with attributes and text content.

To create an ‘id’ element is straightforward:

xml.id 'my-id-here'

and then to put that tag in the ‘foo’ namespace you need:

xml.foo :id, 'my-id-here'

To create children of that element (say xhtml content in an atom feed) you need:

xml.content :type => 'xhtml' do
  xml.xhtml :div do
    xml.p entry.excerpt

And the final piece of the puzzle, and the end to that particular bout of frustration is the text! method. To use my exact example:

xml.georss :point, :featuretypetag => 'wifi' do
  xml.text! entry.latitude + ' ' + entry.longitude

Aug 06

Feeds in the Blogger Beta Updates

After TechCrunch posted about the new version of blogger (currently in beta) I decided to give it a look, particularly to see what was going on with their feed support as TechCrunch claim that blogger would be switching to RSS2 for its feeds (revisiting TechCrunch it seems they’re now saying RSS2 will be offered in addition to atom so I don’t know if I misread that or it’s been updated. Personally I don’t see the point of adding RSS2 when you have Atom, and wonder if it might be confusing for some users, but I guess someone must disagree).

Creating a new blog on the beta service was as easy as we’ve come to expect and publishing an entry definitely feels faster, even if a single entry isn’t really a good basis for comparison. It’s nice to see tag support (even if they’ve chosen to call them ‘labels’) and their inclusion will definitely make projects like my Greenbelt Collage much easier to explain to users.

So far, it looks as though blogger is sticking with atom with feeds switched on by default, and finally upgrading to valid 1.0 feeds for both entries and comments. The default setting is for the full text of both posts and comments to be available in Atom 1.0 feeds, with links to those feeds included by default in the templates. Support of Atom 1.0 rather than RSS 2 is very good news for those of us developing tools that aggregate or remix feed content, if for nothing more than its support for unique IDs.

Unfortunately there don’t seem to be autodiscovery links in the page headers and with the ability to edit the HTML directly not yet in place, there’s not even a way to add them manually. As feed support in browsers and OSs becomes more commonplace, it’s definitely to be hoped that autodiscovery links will be included by default to help keep feed support consistent.

Tags: , , , ,

Oct 05

XML_Feed_Parser: Now in PEAR

On Monday morning I received noticed that XML_Feed_Parser had been accepted into PEAR. The voting process brought a few useful comments, and the latest version cleans up a few of those issues, including adding a custom Exception class.

You can now find the package’s homepage on the PEAR site and it is also stored in the PEAR CVS repository for those who want to get the latest development version or check the source before downloading. PEAR users can get the latest version with:

% pear install XML_Feed_Parser-alpha

I’m hoping to start adding test cases that use character encodings other than UTF-8 and ISO-8859-1 very soon.

Sep 05

Feed Parser: Unit Testing Results

We’ve been away for the past week and time on planes and trains allowed me to focus on some simple unit tests for XML_Feed_Parser. I based the tests on the sample feeds provided in each format’s specification and was able to fix numerous bugs that arose during the testing process, with the only one remaining being some problems handling XML entities.

The tests also allowed me to do some refactoring, identifying a few methods that could be eliminated or merged into the parent class since they were the same across all feed types.

The new version is available at the usual location.

Jun 05

Tinkering with Atom

For a while now I’ve been talking about writing some classes to ease use of Atom in PHP, primarily as a base for an implementation of the Atom Publishing/Editing Protocol. I’ve been putting it off, partly due to time restrictions, and partly because the Atom Syndication Format isn’t quite an approved standard yet and I didn’t want to have to spend too much time keeping up with drafts.

Atom is rapidly approaching stability, and a little time over the weekend has led me to start work on some code. Rather than just write a parser for Atom I decided to follow the lead set by Mark Pilgrim‘s Universal Feed Parser, which makes working with feeds in python a breeze, and have begun to shape some classes that I hope will provide a similar level of flexibility and abstraction for PHP coders.

At the moment, the implementation consists of two (PHP5-only) classes. The main FeedParser class will operate on either an XML file passed in as a string, or a URL/filename, and will then give some access to some of the feed properties (through overloading). Parsing is mainly provided using PHP5’s built in DOM support, with a little use of SimpleXML

The object can also be iterated over, returning each time an object representing one item from a given feed, from which elements and attributes can be retrieved. Soon I hope to add a mechanism for accessing an element by ID, as well as an improved mechanism for retrieving feeds over HTTP that will honour returned status codes, and support for feed validation. Right now, access works along the lines of:

require_once "XML_FeedParser.php";

$parse = new XML_FeedParser($atom_feed_url);
echo "<ul>";
foreach ($parse as $item) {
	$property = 'dc:subject';
	$subjects = $item->$property;
	if (is_array($subjects)) {
		$subjects = join(", ", $subjects);
	$title = $item->title;
    echo "<li>$title: $subjects</li>";
echo "</ul>";

Where an element is requested that occurs only once and whose only child is a text node, the text will be returned. If the element occurs multiple times, or has further elements as children, an array is returned.

Further work is currently needed to provide useful abstractions. Mapping between element names used in different formats is high on the list, as are a unified mechanism for working with dates in feeds, and a cleaner way to access certain attributes. Where multiple links are provided, I hope to provide a way of accessing them using ‘rel’ and ‘type’ attributes. I’m still deliberating whether the best way of achieving all this is to have a separate class (implementing a consistent interface) for each syndication format or careful use of conditional code within a single class.

There is some rudimentary support for namespaces provided. I have used the namespace to identifier mapping from the Universal Feed Parser to allow this, meaning that if the request is for, say, dc:subject, the parser will recognise that as a Dublin Core property and search the feed appropriately. The implementation is far from perfect, but is probably the best tradeoff between usability and flexibility that can be hoped for at this stage.

The other key aspect that I’m considering adding is a way to add/edit/remove items from a feed. If I do that, I’ll probably change the name of the package.

For now, I’ve packaged the work to date as a PEAR-compatible package that will be installed as XML_FeedParser. You can get the package file here or see the source code for the main class and the prototype item class (the latter URL may change as the implementation develops).