Saturday, June 23, 2012

Stardog and Spring Framework Example

Ever since the initial release of Stardog Spring support, I wanted to create a simple example application for people to learn how to use the Spring Beans and introduce semantic web technology using Stardog into traditional Spring technology stack implementations.  So I'm happy to announce today a small sample application is now available on Github, the Stardog PetStore.  Following the Spring PetClinic example, the Pet Store uses the metaphor of a store to go buy a pet - in this case, dogs!

What we'll see in the sample application is:
  • A Gradle build that references the Stardog library folder, one of the easiest ways to pull Stardog into a build
  • A basic Spring 3.1 Web MVC application, with one controller, and a couple views.
  • The usage of traditional Spring beans files, and some stereotype annotations for autowiring of the Data Access Object
  • Usage of the SnarlTemplate class to create a data access object for a POJO
  • Usage of the DataImporter capability to load some triples at initialization time

There are, of course, lots of fun things going on with Spring 3.1 with Java configurations, javax.inject annotations, environment abstraction, etc.  This sample was kept simple by following the standard 'Simple MVC Template' project available in SpringSource Toolsuite, so anyone learning Spring can follow the parallels of those samples.  Also SnarlTemplate is analogous to JdbcTemplate, so it uses the traditional Data Access Object design pattern as opposed to new rich domain models and Spring Data.  Like JdbcTemplate, this gives full control over the native APIs and lets the mappings manipulate or use as much of the underlying system as necessary.  in our case, mapping to triples, naming our properties with URIs (i.e. RDF predicates) is a good reason to have this access.  Using Stardog Empire support for RDF backed JPA and Spring Data JPA Repositories is certainly on the TODO list and a good evolutionary next step.

The prerequisite steps for this tutorial are:
  1. Obtain Stardog from and unzip somewhere, make sure license is in Stardog home
  2. Create a database called 'petstore', e.g. "stardog-admin create -n petstore"
  3. Make sure you have Gradle 1.0 build available, command line, Eclipse, etc

Let's kick things off with the build.  After checking out the project from Github, update the build.gradle file and set the location where the Stardog/lib folder exists.

The next step is to run the gradle build.  I recommend the recently released Gradle 1.0 and SpringSource Toolsuite 2.9.2, since it lets you specify the gradle folder directly.  Command line builds with Gradle also work nicely.

You'll see the Stardog Spring beans in the root application context, where we are connecting to Stardog via their SNARL protocol.  The only requisite step here is to follow the Stardog documentation and create a database called 'petstore', i.e. "stardog-admin create -n petstore."

The spring/appServlet/servlet-context.xml contains the standard Spring MVC related beans, and instructs Spring to component scan the com.example.stardog package.  From here it will find the HomeController, DogDAO and wire them togeter with the corresponding SnarlTemplate and DataSource defined above.

Looking at the HomeController, we see a run of the mill Spring controller with the following URLs:
  • "/" - the default list of dogs in the store
  • "/create" - the form for adding a new dog
  • "/delete/id" - the GET URL to remove a dog
In all cases, the controller operates on a DAO to retrieve and manipulate the Dog POJO.  The Dog POJO itself has three properties:
  • Name (String, will be referenced inside a URL for the RDF subject)
  • Wiki URL (e.g. the wikipedia page for the breed)
  • Photo URL (e.g. a wikipedia page)
The DogDAO is where the interesting intersection with Stardog and Spring happens.  Each of the usual persistence methods (list, get, add, update, remove) are backed by operations on the SnarlTemplate.  The URL properties used for RDF creation are referenced in a Constants enum. In this case I reused pieces of the FOAF vocabulary - it's not hard to imagine a linked data query helping to fill out more releated information about the subject in question.

Design note: As an aside, creating the DogDAO for pure domain object abstraction highlighted the need to enhance the SnarlTemplate with more of the equivalent methods like JdbcTemplate (e.g. queryForObject), and support Spring TX management.

If everything works out correctly for you, you'll be able to browse and see a couple of entries listed on the web page.

Default List of Dogs in the Store

The list of dogs gets loaded from a dogs.n3 file, found in src/main/resources.

Lessons Learned from this sample:
  1.  Enterprise grade applications built with Semtech is certainly possible, and with proper encapsulation the RDF and SPARQL can live in the data layer, leaving the business logic the usual bundle of POJO joy
  2. Stardog provides a rich development experience, friendly to Java developers
  3. Gradle saves a tremendeous amount of time by being able to interweave in file system trees along side Maven style dependencies
  4. There is an opportunity for balancing the encapsulation of persistence information (i.e. predicate URIs), business logic, and semantic web exposure (i.e. generating RDFa, RDF representations of POJO resources or REST services)
 My objective is to maintain this example project as a showcase of Semantic web capability and add to it:
  • Linked Data de-reference (e.g. using Spring Jena to query DBPedia)
  • Spring Content Negotiators to expose an RDF resource or RESTful RDF service maybe with JSON-LD
  • Add Empire and a JPA sytle example so SnarlTemplate and JPA can be compared and contrasted
  • Add a few more relationships and triples to showcase the power of SPARQL


  1. PetStore Sample on Github
  2. Stardog - Download and obtain license here
  3. Stardog Docs - Includes chapters on Stardog Spring
  4. Clark & Parsia - creators of Stardog
  5. Spring 3.1 Documentation
  6. Gradle and SpringSource Toolsuite Tutorial