# Tutorial 2: Developing RDF backed RESTful applications

Author: Reto Bachmann-Gmür and Tsuyoshi Ito - clerezza.org

Contributor: Hasan - clerezza.org

## Table of Contents

1. Introduction

2. Setting up the project

3. Creating an accessible service

4. Build

5. Installing the bundle

5. Test your bundle

6. References

## 1. Introduction

REST [1] is a software architecture style applicable to the World Wide Web. With the advent of the Semantic Web this resource oriented design shows its strength. The web of documents evolves seamlessly to a web of data and knowledge.

RESTful Web applications are designed based on a set of REST principles. In this introductory tutorial you'll learn how to develop a RESTful application that delivers human readable semantic content which is stored in a triple store.

Therefore, you will learn about SCB [2] and Triaxrs [3] and how to use them to develop an RDF-backed RESTful Web application. The time it takes to go through this tutorial is around 30 minutes.

## 2. Setting up the project

Create a maven project with the following parent and dependencies (see the Triaxrs Tutorial 1 (Developing a RESTful Web Application for OSGi Runtime Environment) for more detail [4]):

First configure the repositories as follows:

<repositories> <repository> <id>clerezza-release</id> <name>clerezza.org distribution repository</name> <url>http://repo.trialox.org/release</url> <layout>default</layout> </repository> <repository> <id>clerezza-snapshot</id> <name>clerezza.org snapshot repository</name> <url>http://repo.trialox.org/snapshot</url> <layout>default</layout> </repository> </repositories> <parent> <artifactId>org.clerezza.parent</artifactId> <groupId>org.clerezza</groupId> <version>0.1-SNAPSHOT</version> //check here for the newest release version or here for newest snapshot version</parent>

It in not necessary to define the `version` parameter of each dependency because they are specified in the parents pom file.

<dependency> <groupId>org.clerezza</groupId> <artifactId>org.clerezza.jaxrs.rdf.providers</artifactId> </dependency> <dependency> <groupId>org.clerezza</groupId> <artifactId>org.clerezza.platform.typerendering.seedsnipe</artifactId> </dependency> <dependency> <groupId>org.clerezza</groupId> <artifactId>org.clerezza.triaxrs</artifactId> </dependency>

Also set packaging to `bundle`

By default the `maven-bundle-plugin` will export the package named <groupId>.<artifactId> and its subpackages, so the exposed components must be defined in a package named that way. In our example we use `org.example.clerezza` as groupId and `combined.tutorial` as artifactId.

## 3. Creating an accessible service

Like in the Triaxrs Tutorial 1 [4] we create a JAX-RS class to get information about persons. To have some data to play with, we will add an RDF file encoded in the Turtle format into the resource tree of our project. Thus, we create the file src/main/resources/org/example/clerezza/combined/tutorial/data.turtle with the following content:

@prefix foaf: <http://xmlns.com/foaf/0.1/>. [ a foaf:Person; foaf:title "Mr"; foaf:name "John Doe"; foaf:mbox <mailto:john@example.org>; foaf:topic_interest <http://dbpedia.org/resource/Category:BBC_television_sitcoms>; foaf:nick "jo" ] . [ a foaf:Person; foaf:title "Mrs"; foaf:name "Jane Bloggs"; foaf:mbox <mailto:jane@example.org>; foaf:openid <http://openid.example.org/jbloggs> ] .

The JAX-RS resource class mentioned above is called in this tutorial `TutorialApp` and looks as follows:

package org.example.clerezza.combined.tutorial; import java.io.InputStream; import java.net.URISyntaxException; import java.net.URL; import java.util.Iterator; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import org.osgi.service.component.ComponentContext; import org.clerezza.platform.typerendering.seedsnipe.SeedsnipeRenderlet; import org.clerezza.platform.typerendering.RenderletManager; import org.clerezza.rdf.ontologies.FOAF; import org.clerezza.rdf.utils.GraphNode; import org.clerezza.rdf.core.ImmutableGraph; import org.clerezza.rdf.core.Graph; import org.clerezza.rdf.core.NonLiteral; import org.clerezza.rdf.core.Triple; import org.clerezza.rdf.core.Graph; import org.clerezza.rdf.core.UriRef; import org.clerezza.rdf.core.access.NoSuchEntityException; import org.clerezza.rdf.core.access.TcManager; import org.clerezza.rdf.core.serializedform.Parser; /** * Get Persons by their email * * @scr.component * @scr.service interface="java.lang.Object" * @scr.property name="javax.ws.rs" type="Boolean" value="true" */ @Path("/foaf") public class TutorialApp { /** * @scr.reference */ TcManager tcManager; /** * @scr.reference */ private RenderletManager renderletManager; private UriRef graphName = new UriRef("http://localhost.mygraph"); @GET @Path("find") @Produces("application/rdf+xml") public ImmutableGraph getPersonRdf(@QueryParam("mbox") String mboxString) { Graph graph = tcManager.getMGraph(graphName); NonLiteral person = getPersonByMbox(mboxString, graph); return new GraphNode(person, graph).getNodeContext(); } @GET @Path("find") @Produces("application/xhtml+xml") public GraphNode getPersonHtml(@QueryParam("mbox") String mboxString) { Graph graph = tcManager.getMGraph(graphName); NonLiteral person = getPersonByMbox(mboxString, graph); return new GraphNode(person, graph); } private NonLiteral getPersonByMbox(String mboxString, Graph graph) { Iterator<Triple> iter = graph.filter(null, FOAF.mbox, new UriRef(mboxString)); NonLiteral person = null; while(iter.hasNext()) { person = iter.next().getSubject(); } return person; } /** * The activate method is called when SCR activates the component configuration. * This method gets the system ImmutableGraph or create a new one if it doesn't exist. * * @param componentContext */ protected void activate(ComponentContext componentContext) { URL templateURL = getClass().getResource("tutorial.xhtml"); try { renderletManager.registerRenderlet(SeedsnipeRenderlet.class .getName(), new UriRef(templateURL.toURI().toString()), FOAF.Person, null, MediaType.APPLICATION_XHTML_XML_TYPE, true); } catch (URISyntaxException ex) { throw new WebApplicationException(ex); } Graph tc; try { tcManager.getMGraph(graphName); } catch (NoSuchEntityException nsee) { tc = tcManager.createMGraph(graphName); InputStream fin = null; fin = getClass().getResourceAsStream("data.turtle"); Parser parser = Parser.getInstance(); tc.addAll(parser.parse(fin, "text/turtle")); } } }

The resource class above provides two resource methods to process GET requests specifying the path /foaf/find. The JAX-RS annotation @Path on TutorialApp sets the path of the resource to “/foaf”, while the JAX-RS annotation @Path on the resource methods `getPersonRdf` and `getPersonHtml` defines the subpath "find". Furthermore, the JAX-RS annotation @Produces defines the list of media types that a Java type or a method can produce. A media type corresponds with the representation of a resource. In this tutorial `getPersonRdf` should produce "application/rdf+xml", whereas `getPersonHtml` should produce "application/xhtml+xml". Both methods accept a parameter, whose value is obtained from the GET request parameter called mbox. This is defined through the JAX-RS annotation @QueryParam.

A resource can have multiple representations. For example, a web page can be represented as html, pdf, plain text, or other representations. The HTTP defines a mechanism known as content negotiation to allow a client (e.g., a web browser) to specify which representation it would like to get from the server. Using JAX-RS we can define a `MessageBodyWriter` which maps a Java type to a representation. In this tutorial `getPersonRdf` returns a ImmutableGraph, whereas `getPersonHtml` returns a GraphNode, which represents a node in the context of a ImmutableGraph. The clerezza platform provides for either resources ImmutableGraph and GraphNode a corresponding `MessageBodyWriter`.

The clerezza platform's `TemplatingMessageBodyWriter` produces a representation of the format "application/xhtml+xml" from a `GraphNode`, whereas the `GraphWriter` produces "application/rdf+xml" from a `ImmutableGraph`. `GraphWriter` is implemented in the maven project org.clerezza.jaxrs.rdf.providers. The `TemplatingMessageBodyWriter` uses a templating engine to render a `GraphNode` based on a predefined template file. In order to allow a different `GraphNode` to be rendered using a different template, each `GraphNode` and template is bound to a specific RDF type.

For the purpose of registering a template, a `RenderletManager` service is made available. In this tutorial, a template (obtained from the file "tutorial.xhtml") is registered for the RDF type FOAF.Person (http://xmlns.com/foaf/0.1/Person). This is done in the `activate` method using the `RenderletManager` service.

In the `activate` method we also use the `TcManager` to get the `Graph` called "http://localhost.mygraph". If this ImmutableGraph doesn't exist, a `NoSuchEntityException` is thrown. In this latter case, we catch this exception and create an `Graph`. Afterwards we add the triples from the file mentioned above into the ImmutableGraph.

The following template renders a FOAF.Person. For easier readability namespaces can be defined. Statements which should be interpreted by the templating engine starts with the character `$`. The templating language allows loops and conditions. More examples are available on the project website of the templating engine (http://clerezza.org/projects/org.clerezza.templating.seedsnipe/documentation/overview.xhtml

<!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" xml:lang="en" lang="en"> <head> ${ns:foaf=http://xmlns.com/foaf/0.1/} <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <title>clerezza - Combined Tutorial</title> </head> <body> <h1>clerezza - Combined Tutorial</h1> <h2>FOAF Person:</h2> <div> <p>Name: ${foaf:title} ${foaf:name}</p> <p>Email: ${foaf:mbox}</p> ${if foaf:nick} <p>Nickname: ${foaf:nick}</p> ${/if} <p>Topic interests: <br /> ${loop} ${foaf:topic_interest}<br /> ${/loop} </p> </div> </body> </html>

## 4. Build

To build the package, execute the command:

$ mvn package

## 5. Installing the bundle in the Clerezza Platform

Download the latest clerezza platform launcher from http://repo.trialox.org/snapshot/org/clerezza/org.clerezza.platform.launcher.sesame/ and start it. Go to http://localhost:8080/user/admin/control-panel (enter username: admin, password; admin) and upload your bundle.

## Test your bundle

Open the URL http://localhost:8080/foaf/find and add the URL parameter `mbox=mailto:john@example.org` to receive information about john

## References

[1] R.T. Fielding: Architectural Styles and the Design of Network-based Software Architectures; CHAPTER 5 Representational State Transfer (REST), 2000, http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm

[2] Clerezza Smart Content Binding SCB http://clerezza.org/projects/org.clerezza.rdf.core/

[3] Clerezza Triaxrshttp://clerezza.org/projects/org.clerezza.triaxrs/

[4] Clerezza Triaxrs Tutorial 1http://clerezza.org/projects/org.clerezza.triaxrs/documentation/tutorial_1.xhtml

That's all folks for this time!