Sunday, July 22, 2012

Simple Guice integration for Dropwizard

If you haven't come across it yet, Dropwizard is a nifty new framework designed to streamline and simplify development of lean web services which are inherently "ops-friendly". By "ops-friendly", I mean that it provides out of the box support for and gentle encouragement to use things like health checks and metrics monitoring. By "lean", I mean that these services are run from within their own JVM processes, with embedded Jetty as a server. This idea of multiple, self-contained, fail-fast processes is best described by the Twelve Factor App.

So with Dropwizard, you extend from the base Service class, and add things to the Environment on startup (e.g. Jersey Resources, Providers, etc). I've created a simple extension to the Service class which does some classpath scanning to automatically install your resources, providers, health checks and tasks for you, via Guice, allowing you to use Dependency Injection throughout your application for object dependencies. Check it out on github! (IMHO) It's quite simple to integrate into your project, and I've found it to be very useful so far, in that I can simply create a new resource class with a @Path annotation, create a constructor marked with @javax.inject.Inject, and it will automatically be wired up and installed into the REST container.

Let me know what you think! If I get enough interest (read: any) then I'll throw up the binaries on an accessible maven repo.

Update (26 Sep): I did end up getting interest, and have since made this available on the central maven repo.

3 comments:

Regler said...

Really nice, though would it be possible for you to add some example of how you are using the implementation together with your DAO-objects (a more full stack example).

acme said...

I really like this solution, but I have a quick question:

I am making the transition from Spring to Guice (I want something much lighter weight and Guice looks good), so I'm a bit of a newbie.

Many of my Dropwizard resources depend on underlying @Singleton services, which in turn rely on data from the Configuration object exposed by run(). I see that gets passed to runWithInjector, but how do I get the Configuration object into the injector?

More specifically, Guice is just created an empty Configuration object to pass to my service implementations, which immediately break because there is no DB connection data.

How to I bind a specific object/singleton (the Configuration) into Guice?

Thanks!

Jared Stehler said...

So what I've done in certain scenarios is pass the configuration into the constructor of my main module class, and then bind that instance to the Configuration.class.

In my Service:



@Override
protected Injector createInjector(MyServiceConfiguration configuration) {
return Guice.createInjector(new MyServiceModule(configuration));
}

And in my injector:

private MyServiceConfiguration configuration;

public MyServiceModule(MyServiceConfiguration configuration){ this.configuration = configuration; }

@Override protected void configure() {
bind(Configuration.class).toInstance(configuration);
}