We have been using restlet (Version 1.1.3) as the web framework on our current project and I thought It might be useful to share our experiences.
Initially we chose it because it seemed a good match to what we wanted to achieve. We wanted to write a pure http interface to our application. Restlet is all about routing http requests to “resources” it maintains the semantics of restful applications and so you have put, post, get, delete methods and resources and representations of these resources. All very restful and good.
It was pretty fast to get going. We knew we were going to use DI in our app and so wanted to configure restlet in that way. Sure enough, there is a spring front controller out of the box.
It also had out-of-the box support for Freemarker. Having used velocity extensively, we had heard good things about freemarker and this seemed a good enough choice as a templating library although we were originally keen to use string template (but that’s another post!).
So we were up and running quite quickly. However there were a few “features” which have made life less than rosy for us. I am going to just briefly list them here. To be fair some of these are due to the Spring integration, which could be avoided.
Inheritance based:
In order to be part of the framework, you have to extend the restlet class “Resource”. This results in several of the issues below.
Verbose spring configuration
Because restlet needs to intantiate new “resources” from spring, it needs to do some of its own injection with things like the response and request (due to the inheritance feature). So you can’t just declare your resource bean in the spring config, you have to wrap it in a class called “SpringFinder”. It ust means that your spring config looks a bit verbose and noisy.
Matching URI patterns:
Restlet has rather a complex URI pattern matcing algorithm. Im sure this has some use somewhere, but involves some kind of weighting strategy (well actually a choice of several). This in itself is not too bad, but to do the simplest thing is not the first configuration. It took a bit of digging about to find out that in order to just exactly match the URI you map in the config, you have to Override the method getMatchingStrategy
and return a value.
A suggestion might be to have the routing algorithm encapsulated as a Strategy object. That way, it could come with a default strategy which is just exact matching, and then if you need the more complex algorithm it would be easy to swap in.
We first noticed this when we mapped a uri something like /contextroot/someentitylist/22
if you try /contextroot/someentitylist/22/foobar
you dont get a 404, it just goes to your resource.
Complex api
Sometimes things seem a little tricky to do. For example, to get the Http headers from the request, you have to get a Form
object which is a bit strange, its like it was re-used just because it sort of looked like a web form, instead of just having a specialised object to represent the headers. I guess that sometimes it seems a little too generic which means you need to do some interpretation of the object model to get what you want.
Noisy logging
We wanted to implement the Cache-Control
and Pragma
headers. It lets us do it but complains noisily in the log output, on the error stream telling us that we shouldnt do this, because It will be implemented in a future version!!. It logs this at SEVERE level!. This is rather patronising and now fills the log file with noise.
Inheritance based (again)
In order to inform the framework that you allow puts and posts, you have to override the methods allowPut()
and allowPost()
All of which led us to create a single derivation of their class and then delegate to new classes of our own devising thus breaking the inheritance tree, or “running away from home”.
Thread Local Storage
While im not necessarily saying TLStorage is a bad thing per se, you do need to be careful in a web app that anything you put on it, you remove at the end of each request processing, because otherwise it just stays there and builds up in the vm. Felix and Martin were looking into some memory leak stuff in our web app and discovered this interesting fact. It was easily fixed by just setting the instances to null at end of request. Maybe we were using the framework incorrectly and so had not called the appropriate sequence, but even so, something so important should be impossible for us to get wrong. I think they used Your Kit for the job which they were pleased with as it pointed them directly at the classes in question.
General vibe
Basically, it feels most of the time that you are being made to jump through hoops to integrate with the framework. I feel that frameworks should be transparent and non-invasive.
What do you think ?
Do you have any experience with Restlet ? Maybe we are just not using it in the right way. I do notice that we are using the stable version so I haven’t looked at what is upcoming.