Ninja, JAX-RS and Servlets

A couple weeks ago I discovered the Ninja web framework via a link on Twitter. It's presented as a Java web framework largely inspired from the Play! framework. What I liked from the very beginning is that it's a Java citizen before all: plays nice with Maven and everything you're used to do with/in a Java project. This is in total opposition to Play! which forces you to use its own tools and way of thinking. Furthermore, Play! (v1) does runtime bytecode manipulation to override the semantics of static fields (replacing them with a ThreadLocal). This is probably the one thing that I dislike the most in Play!: it's no longer Java.

Ninja web framework: Play! framework done right?
Looks a lot like JAX-RS though; I think I'll stick with that one.

ninjaframework.org/introduction.h…

— Thomas Broyer (@tbroyer) April 5, 2013

I like Ninja's minimalism but I think it can do better (and I'm not even talking about the rather limit set of features compared to Play!). For example, Play! is advertized as being highly scalable, partly due to using non-blocking I/O and more specifically Netty. Ninja also talks about Netty being a potential deployment target, but had a strong dependency on the Servlets API. A few hours of hacking later, Servlets are only an implementation detail.

I'm looking at OAuth 2.0 for that project at work where we'll use Play! (v2) so I wondered how it'd look like in Ninja, and I found out there's no clean way to communicate between a ninja.Filter and a controller. So I proposed adding getAttribute and setAttribute (it turns out that Play! already has those methods).

Digging deeper in Ninja's internals, I found a couple other things I'd like to change, and I started working on them, along with Grizzly and Netty backends. Raphael A. Bauer is very open and very reactive, so overall working on Ninja was a pleasure.

But there was still something that bugged me, and I couln't put words on it at the time.

The more I look at frameworks like Play or Ninja, the more I want to go “no framework”. Will have to experiment with that…

— Thomas Broyer (@tbroyer) April 7, 2013

Don't get me wrong: I'm not saying Play or Ninja are bad; just that, 1 or 2 days in, I really can't say I'm in love.

— Thomas Broyer (@tbroyer) April 7, 2013

Overall, I think it boils done to the fact that I don't like frameworks. I largely prefer libraries. Play! is a full-stack framework, and Ninja borrows from it by providing the router, the templating engine (Freemarker), a simple API to send mails, etc.

JAX-RS 2.0

At work, I'm also working concurrently on a project using JAX-RS 2.0 and I really like it. JAX-RS provides its own dependency injection mechanism but we made it play nicely with Guice (and I even experimented with replacing Guice with Dagger). It feels a bit weird to have two DI framework (Jersey comes with its own DI framework called HK2) coexisting in the same app but Jersey is only one implementation of JAX-RS (just like Guice and Dagger are implementation of JSR 330, except JSR 330 doesn't deal with how you configure injection).

Hacking on Ninja+Grizzly the other day, it happened to me that I actually want it to be more like JAX-RX. The main differences between them would be:

Overall, I prefer JAX-RS as it allows you to compose the parts you want (template engine, etc.) as you want, at a somewhat negligible cost (compared to the flexibility it brings!)

Servlets 3.1

Approximately at the same moment, I see something about Servlets 3.1 so I go check the spec to see what's new. I end up reading the spec almost back to back, and I generally like what I see. The one advantage compared to Ninja and JAX-RS is that it has support for NIO (already implemented in Grizzly 3.0-SNAPSHOT, among others), but it's lacking advanced routing (with extraction of path-parameters from the URL, and construction of links from a URL-Template/pattern) and I don't know of any such thing as a standalone library.

Lightweight web “framework” (toolkit?): Servlet 3.1 + some router + DI container + template engine. The problem is to find a router…

— Thomas Broyer (@tbroyer) April 8, 2013

I unfortunately haven't had the time yet to do the experiment. I'm not even sure a full-blown router component is really needed after all (it really depends how you want your URLs to look like).

Conclusion

I haven't given much time to Ninja but in the end I think I much prefer JAX-RS 2.0.

Servlets 3.1 look very interesting but are even lower-level. Depending on your needs, I think it can be a better choice. It's lightweight enough that it can be implemented on top of many lower-level APIs (Netty, Grizzly, Jetty, etc.) so it provides a lightweight portable API (but JAX-RS is similar).

The only missing bit to JAX-RS (and Ninja) compared to Servlets 3.1 (and Play! v2) is the support for NIO. It's apparently on the radar but will go through experiments with proprietary (Jersey vs. RESTEasy vs. …) APIs. Now it hasn't really been an issue 'til now and it won't be an issue in practice for many of us (many templating engines and other renderers/serializers don't make use of NIO to begin with), but still.

So what?

Oh, this was all just musings on web frameworks from my past 2 weeks with them. I didn't talk about Play! as I haven't yet spent much time on it (I focused on SBT for now, which I must say I really don't like) nor that experiment (running in production for a couple years though) from Tim Boudreau:

Interesting new Java web framework by @kablosna; actor pattern, based on Netty and Guice.timboudreau.com/blog/Acteur/re…

— Thomas Broyer (@tbroyer) April 8, 2013

I've always tried to favor standard APIs anyway, by principle and to avoid lock-in, so I'd rather stick to JAX-RS and Servlets (and JAX-RS can be implemented on top of Servlets to be deployed everywhere servlets can, including e.g. Google AppEngine), but those other frameworks bring interesting things. I'll have to learn Play! (v2) at work anyway, let's see how it goes…