Jersey is my goto software for developing REST services and then I came across Dropwizard. It is a simple and neat framework written on top of Jersey and glues together all essential libraries for creating production ready services.
Before externalizing a web service, it must be operationally ready to take real world traffic and provide HA. So many engineers end up writing health checks, enabling the required logs and metrics metrics etc. All of these features are available out of the box in Dropwizard. Furthermore, it has nice features such as HTTP client for invoking other services, authentication, integration with Hibernate and DI.
So, while the documentation is straight forward and 'Getting Started' guide does get you started, integration with Spring and JPA via Hibernate requires some work. This article will help you with that assuming you have a working service written using Dropwizard.
1. Wiring up Spring and Dropwizard. HelloWorldApplication is the entry point to the Dropwizard application. The run method is where we initialize Spring.
It is a standard way to initialize Spring. Two important points to note here. One, no need to register resources explicitly. Spring will look for classes annotated with @PATH and register it with Dropwizard. Second is to include MyAppSpringConfiguration which provides additional resources to be included.
2. Definition for MyAppSpringConfiguration is below:
For complete working example, see https://github.com/nchandra/SampleDropwizardService
Before externalizing a web service, it must be operationally ready to take real world traffic and provide HA. So many engineers end up writing health checks, enabling the required logs and metrics metrics etc. All of these features are available out of the box in Dropwizard. Furthermore, it has nice features such as HTTP client for invoking other services, authentication, integration with Hibernate and DI.
So, while the documentation is straight forward and 'Getting Started' guide does get you started, integration with Spring and JPA via Hibernate requires some work. This article will help you with that assuming you have a working service written using Dropwizard.
1. Wiring up Spring and Dropwizard. HelloWorldApplication is the entry point to the Dropwizard application. The run method is where we initialize Spring.
@Override
public void run(HelloWorldConfiguration configuration,
Environment environment) {
//init Spring context
//before we init the app context, we have to create a parent context with all the config objects others rely on to get initialized
AnnotationConfigWebApplicationContext parent = new AnnotationConfigWebApplicationContext();
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
parent.refresh();
parent.getBeanFactory().registerSingleton("configuration", configuration);
parent.registerShutdownHook();
parent.start();
//the real main app context has a link to the parent context
ctx.setParent(parent);
ctx.register(MyAppSpringConfiguration.class);
ctx.refresh();
ctx.registerShutdownHook();
ctx.start();
//now that Spring is started, let's get all the beans that matter into DropWizard
//health checks
Map healthChecks = ctx.getBeansOfType(HealthCheck.class);
for(Map.Entry entry : healthChecks.entrySet()) {
environment.healthChecks().register("template", entry.getValue());
}
//resources
Map resources = ctx.getBeansWithAnnotation(Path.class);
for(Map.Entry entry : resources.entrySet()) {
environment.jersey().register(entry.getValue());
}
//last, but not least,let's link Spring to the embedded Jetty in Dropwizard
environment.servlets().addServletListeners(new SpringContextLoaderListener(ctx));
}
It is a standard way to initialize Spring. Two important points to note here. One, no need to register resources explicitly. Spring will look for classes annotated with @PATH and register it with Dropwizard. Second is to include MyAppSpringConfiguration which provides additional resources to be included.
2. Definition for MyAppSpringConfiguration is below:
/**
Main Spring Configuration
*/
@Configuration
@ImportResource({ "classpath:spring/applicationContext.xml", "classpath:spring/dao.xml" })
@ComponentScan(basePackages = {"com.nishant.example"})
public class MyAppSpringConfiguration {
}
3. Next, annotate the resource class with @Service annotation and we are ready!
@Service
@Path("/hello-world")
@Produces(MediaType.APPLICATION_JSON)
public class HelloWorldResource {
@Autowired
private HelloWorldConfiguration configuration;
private final AtomicLong counter = new AtomicLong();
@GET
@Timed
public Saying sayHello(@QueryParam("name") Optional name) {
final String value = String.format(configuration.getTemplate(), name.or(configuration.getDefaultName()));
return new Saying(counter.incrementAndGet(), value);
}
}
For complete working example, see https://github.com/nchandra/SampleDropwizardService