Rickard Oberg is popular among Java developers. He has given seminars at all main Java conferences world wide. He worked as an architect at JBoss and other popular OpenSource Java frameworks, and wrote a book on RMI. In recent years, he has become famous as an Aspect Oriented Programming (AOP) crusader. He has worked with bleeding edge AOP in a portal product that has become a great commercial success, and is currently working on Qi4j at Jayway. Rickard is a DZone MVB and is not an employee of DZone and has posted 16 posts at DZone. You can read more from them at their website. View Full User Profile

Qi4j: REST EntityStore and SPARQL EntityFinder = rich client web apps!

08.18.2008
| 6902 views |
  • submit to reddit
From my work on SiteVision I've become quite fond of writing rich clients using applets or JavaWebStart, with Swing, and then connect back to the server for state. I can understand why not so many others are doing it though, since you more or less need a decent framework to handle all the issues, and as far as I know there aren't any around.

Now I'm in the process of adding this functionality to Qi4j! There are two parts to using objects/entities on the client: finding them and loading/storing them. In Qi4j there are two interfaces EntityFinder and EntityStore which respectively deal with these things.

What I have done now is to implement a REST-backend which allows you to access Entity-state through HTTP. Basically, the state of each Entity can be accessed through the URL /qi4j/entity/{type}/{id}, which will return the state as RDF/XML, along with HTTP headers like version and last-modified timestamps. I've then implemented a client-side EntityStore which accesses this REST-backend, so that for someone writing Java clients it is all transparent that the state is being accessed from some remote HTTP-server. When state has been changed it is PUT back to the server, with version checks being performed properly. The state can then be stored using whatever EntityStore is configured on the server, such as Neo4j, Amazon S3, JDBM, or even a database (for those who are so inclined).

For the finder part I have implemented a SPARQL backend, which internally delegates to Sesame2, which is the same default index/query that is used to find Entities in general. This in itself is pretty cool, because it means that you can write your domain model in Java, have it be automatically persisted in a store like Neo4j, and then with no extra effort expose it through SPARQL for AJAX webapps to consume (both RDF/XML and JSON output is supported today). Minimally writing a domain model only involves writing Java interfaces (no classes), so it's pretty easy to get started.

Anyway, I have also implemented a SPARQL EntityFinder for the client, so that they can lookup Entities remotely. If you put these two together you have a complete solution for finding and working with Entities remotely, and it's all based on REST principles. This means, for example, that if the clients are doing the same query over and over, and it bogs down the server, then put an Apache proxy server in between, and let it cache the SPARQL requests for some time. Or let it cache Entity state if that is taking too long. Since it's just HTTP and REST and the URL's are great as cache keys it's a matter of configuration to fix performance issues. Neat!

Here's an example from our testcases which finds Entities in a UnitOfWork and then iterates and prints out some state. Under the covers this tests the SPARQL and REST backends.

UnitOfWork unitOfWork = unitOfWorkFactory.newUnitOfWork();
try
{
// Find all Entities of type TestEntity - test SPARQL EntityFinder
Query query = unitOfWork.queryBuilderFactory().newQueryBuilder( TestEntity.class ).newQuery();

// Iterate and print out the name property - test REST EntityStore
for( TestEntity testEntity : query )
{
System.out.println( testEntity.name().get() );
}
}
finally
{
unitOfWork.discard();
}


Neat!
References
Published at DZone with permission of Rickard Oberg, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)