Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


"Getting Real" with RDF and SPARQL : Page 2

"Getting Real" is an agile approach to web application development. This article explains how it can be successfully combined with the flexibility of semantic web technologies.

RDF-generating Forms
For easier editing, separate the form definition method (dooit/Dooit_getItemForm.php) from the main controller. If you open it in a text editor (or see Listing 1, which is a copy of the method), you can see that the form is built from a simple array of field definitions. The editable fields section is where you define the visible input fields. Following the mockup, only two fields are considered for now, the to-do item's summary and a comma-separated list of tags:

... /* editable fields */ 'summary' => array('required', 'label' => 'Summary', 'term' => 'ical:summary', ), 'tags' => array('required', 'label' => 'Tags', 'term' => 'dc:subject', 'value_type' => 'csv', 'info' => 'comma-separated' ), ...

Figure 3. To-do Item Form: The underlying system auto-generates RDF from the provided form field definitions. It also assigns a web-friendly identifier to each created entry, which becomes handy should you want to publish your to-do list at some later stage, or if you plan to combine it with external data sources.
The term key is important, it indicates the RDF relation to use when the submitted form data is converted to RDF triples (namespace prefixes are defined in config/sys.php). Figure 3 shows the HTML form generated by these field definitions.

What exactly happens when the form is submitted? The framework auto-generates an RDF graph by combining the received data with the term indicators specified in the form definition. These triples are then saved using a SPARQL INSERT query. SPARQL (http://www.w3.org/TR/rdf-sparql-query/), the RDF query language, works similar to SQL, but it is optimized for graph-shaped data and web repositories.

Write operations in SPARQL are not standardized yet, but there is only a small number of related proposals and they are likely to converge sooner or later (dooit uses SPARQL+ internally to enable INSERT operations).

Building a simple RDF graph from the form values can help you keep the amount of custom code at a minimum, which in turn minimizes the cost of changing your application later. Before you start thinking of new features, you still have to replace the static mockup lists (active and completed items and tags) with real data.

SPARQL-driven Views
As already mentioned above, using SPARQL as a data access mechanism allows you to query your dataset at the graph, not at the storage level. SPARQL has some additional benefits (such as multiple result structures and formats, or being able to retrieve data from remote RDF repositories), but it is basically like using SQL against a very simple, three-column table layout:

DESCRIBE ?todo WHERE { ?todo a ical:Vtodo ; ical:status "done" ; dct:modified ?datetime . } ORDER BY DESC(?datetime) LIMIT 5

This DESCRIBE query returns the five most current to-do items marked as "done." The results are then used to populate the field section of the to-do item template (dooit/t_item.php contains the complete template):

<div class="ical-summary"> <?php echo $t_vals[$ical . 'summary'][0]['value'] ?> </div> <div class="ical-categories"> <?php foreach ($t_vals[$dc . 'subject'] as $i => $o) { echo '<a class="dc-subject" href="' .$this->a['handler_rel_base'].'tag/'.urlencode($o['value']). '">' . $o['value'] . '</a>'; } ?> </div>

These views probably look familiar if you have worked with template-based systems before. There is not much that RDF or SPARQL can optimize here. The template pre-processing could be improved, so that you wouldn't have to use long, namespaced keys, but for the purpose of this article, it seemed to make sense not to hide RDF completely.

Finishing a first-running version from here just means writing a few parameterized SPARQL queries (for active items, completed items, and tags) and tweaking the associated templates. In a last step, completing or re-activating to-dos is implemented via a JavaScript call that triggers a SPARQL operation, which in turn changes the item's status and modification date:

// resource identifier and tick action // are sent via a POST parameter $res = $this->p('item'); $status = $this->p('tick-action') == 'on' ? '' : 'done'; $now = Trice::getXSDDate(time(), 1); $g = str_replace('#self', '', $res); // update the relevant triples $store->query('DELETE FROM <'.$g.'> { <'.$res.'> ical:status ?status ; dct:modified ?modified . }'); $store->query('INSERT INTO <'.$g.'> { <'.$res.'> ical:status "'.$status.'" ; dct:modified "'.$now.'" . }');

Figure 4. First Version of Dooit: The initial release allows creating, editing, tagging, deleting, filtering, and completing to-do items.
A screenshot of the final application is shown in Figure 4.

Keeping It Real
Congratulations, you managed to benefit from RDF's generic data model and the simple SPARQL query language to quickly implement a running application (Click here if you are interested in seeing how long it took to build dooit) and with very little custom code (about 15KB of PHP and J avaScript). Equally important for an early first release, however, is the ability to keep iterating to improve the application—and ideally without losing agility. You should perform at least one test to verify that the RDF system stays flexible. The first thing you may want to improve in dooit is probably item ordering, maybe by adding a "priority" field and using that for sorting. Add a new field to the form builder (dooit/Dooit_getItemForm.php), maybe after the tags definition:

'prio' => array( 'type' => 'selection', 'label' => 'Priority', 'term' => 'dooit:priority', 'options' => array('A' => 'A', 'B' => 'B', 'C' => 'C') ),

If you do not want to check the ical vocabulary for a possible matching term, you can use the ad-hoc property instead. The editing form contains an additional "Priority" drop-down now and the specified value is saved without the need for any further code or database change.

The views are not affected yet. To use the new attribute and sort the item list by priorities, you simply call the query builder with a different sort argument. Open dooit/t_items.php, and change the second parameter in getItemListHTML from ical:summary to the newly introduced dooit:priority. The to-do items are now sorted by priority values. Finally, you may want to display priorities in the item template (dooit/t_item.php):

<div class="ical-summary"> [<?php echo $t_vals[$dooit . 'priority'][0]['value'] ?>] <?php echo $t_vals[$ical . 'summary'][0]['value'] ?> </div>

In three simple steps, you added a new field and improved the application, without writing a new method or having to touch the database. You can add more fields and features the same way.

What’s Next?

Figure 5. SPARQL Interface: The SPARQL protocol simplifies the deployment of APIs. It can also be used to debug and experiment with application data.
This was just a basic introduction to agile web development with RDF. To get a closer look at the internal triple data and RDF's standardized