7 May 2008

RESTful TopicMaps framework : RESTMap

Here's a little something I've been fiddling with for the last year or so. In between all the crazy stuff I've tweaked, fiddled and modified on this little hobby project of mine, going from a conceptual prototype of "something" to a quite usable framework for serious application development. The main features and components are;
  • REST - both internal and external interaction use proper REST, with a strong focus on the "state as a web of resources" part of it.
  • Cool URIs - All URIs in the system are promoted to be cool and simple, making them easy to link to and intuitive to use.
  • Topic Maps - What's more natural to a web of identifiable resources than a map of topics, all interconnected? Ever application and sub-application have a Topic Map that can link to further maps, and there's a fully RESTful interface to the query and action parts of it.
  • LAMP/WAMP - I use Linux/Windows with Apache2, PDO for persistence (which to many will be MySQL, but I actually prefer SQLite for this one; kicks ass!), and finally PHP 5.2.*. This stack is easy to install and maintain, is widely used and supported, and I've designed the system such that it's dead easy to install on top.
  • Zend Framework - I use and extend this framework. It's bloody great.
  • XSLT/ XML templating - I've created an XSLT framework that is able to mimic many of XSLTs ways of working in XML input files, meaning we've got a neat, small, fast and sexy XML-based templating language.
In terms of Topic Maps I've designed a new simple notation language which I use for all interaction, so my XTM 1.0 and 2.0 importers and exporters use this new one as mediator. It doesn't have a name yet, but it basically look something like this;
topic #ajohannesen
name "Alexander Johannesen"
name "Alex" #shortname scope #small-world
name "shelterit" #username
type #person
type #human
psi http://psi.shelter.nu/persona#ego
psi http://psi.ontopia.org/people/ajohanne
occurrence http://shelter.nu/ #website
occurrence http://shelter.nu/blog/ #blog
occurrence "Blue" #favourite-color

type #marrige
member #ajohannesen as #husband
member #jajohannesen as #wife
It's a YAML friendly format, slightly more verbose than LTM but not as crazy as XTM 1.0. It's ideal for streaming Topic Maps data from other sources, but there's nothing about it which I think you can't work out by simply looking at it.

A few words on the persistence layer here; I use an SQL based database, in my case the excellent SQLite project. The data model recreates the Topic Maps Reference Model, which has a few setups to support the TM Data Model, much in the same way that Robert Barta's Perl::TM libraries does it; going back to frames theory for brilliant caching and flexibility (making querying the maps functionally complete), with key/value pairs to create the model you're after. This works great and really fast in systems that use natural indexes (such as BerkleyDB and SQLite) but mght be slow on more traditional relational database systems such as MySQL (but untested for now), and the performance is excellent even on somewhat large datasets (ca. 100.000 topics, 300.000 associations on my 2.4GHz laptop, doing "normal" querying flies smoothly, but of course your mileage will vary), so I'm quite pleased with it so far.

Now on to the programming part of the project. When packaging your application up in a reasonable file structure I'm using a few tricks and a couple of new PHP 5.2 features. The whole system consists of mainly two objects, one for the environment, and one for the application. The environment object is in charge of state, request variables and all paths, includes and otherwise, and is invoked as such;
// Create an environment instance (inserting current file's filename as a
// way for the framework to figure out directory structures and such)
// The framework handles the environment and auxiliary classes
$env = new xs_Environment ( __FILE__ ) ;

// Initialize some objects after the framework is instantiated
$env->init() ;
Notice that I pass in __FILE__, a constant value for the current file path (which will always be the main index.php file) , which the system parses to find out where in the file system we're running from, and creates include paths from it. Through this there is no installation or configuration needed for this part of the system. (In fact, the whole index.php file consists of 11 lines of very readable code, so you'll work this one out for sure) We also use autoloading of classes, defined through the environment as well, which is great, and works side by side the Zend Framework.

The application object is more or less a small framework class that looks in special directories for action classes, and invoke them as specified and dealing with the Topic Maps interactions, and is invoked as such;
// Instantiate our application (injecting environment)
$application = new xs_Application ( $env ) ;

// Go mama! (Meaning, figure out the request and do the associated action classes)
$application->action () ;
We inject the environment instance into the application, and off we go to get some action(). The whole application is driven by a stack of results from various tasks, and these are passed from the application through to displaying the response. The templating language is all XML based, and the stack is passed as XML to the XSLT framework. We use content identificators to work with the data passed, guaranteeing XHTML 1.0 Strict output, clean XML templates, reuse and XPath handling of all your GUI needs.

Here's a typical action class for invocation on a given URI;
class xs_REST_Action_Implementor extends xs_REST_Action {

function uri_template () {
return "{concept}/{id}/{selected}/{special}/{filter}" ;

function GET () {

$this->title = 'TM : Get : current TopicMap by ID' ;

$this->request->set ( 'output', 'xml' ) ;

$this->stack->add ( 'topic_maps', $this->topicMap->getTopicById (
$this->breakdown->get ( 'selected' )
) ) ;

Here we override two default methods of the xs_REST_Action class to do something special here, and we add our result to the stack that gets shifted into the GUI layer later. We also force the output here to be XML, and the $this->breakdown class instance is a representation of the various parts of the URL broken down into its parts based on the URI template we defined here in the function uri_template() method. Pretty simple, really.


I'm not ready to go public with the framework yet, and I'm still polishing it up, but rest assured it's going to be open-sourced under the xSiteable moniker of projects. I'm quite happy with this one, though, because it makes a few exciting design choices, mostly in the twilight between RESTful architecture and Topic Maps. Once I've finished implementing a testing integration framework (see my previous whine) and made sure every part of the Topic Maps engine is solid (I'm trying to use the new Topic Maps test cases for this), I'll release an early beta.

Other things I'm evaluating is full support for the Atom Publishing Protocol (APP) which is a slapstick version of what Topic Maps can do (I can recreate APP in the internal "objects within objects" model), and support for content-type negotiation with a registry. Any other things I should think about? Thoughts? Questions?

1 comment:

  1. goddavs!

    jeg tjekket like ind paa profiler med sektor teknologi (for at si hvor mange blandt de foerste tretti - femti der var intressert af bdsm, tjekker alle yrken og kategorier jeg fandt bland de foerste femti med det intresset) og fandt glaedeligt nok en barok-intresseret man

    kolla bloggen deretour, derpaa venstrespalten, derpaa "Own" Sites, der finder du Mes Compositions sur Antimodernism, og de varierer i stil nogen steder mellem barok, wienklassisk og folkmusik