13 Comments

Serving Static Assets with DropWizard

Over the last few months, I’ve had the opportunity to do a lot of work with DropWizard, an awesome Java web framework for developing RESTful web services.

I was recently prototyping a small application, and I wanted to serve static files directly from DropWizard. While this isn’t what DropWizard is primarily designed to do, I didn’t want to go through the process of setting up another web server just to serve static assets for a prototype. While DropWizard has some out-of-the-box support for serving static assets, I found the documentation surrounding it to be incomplete and confusing. It actually took me a couple hours of debugging to figure out how to do exactly what I wanted, So I thought I would document what I learned here.

My end goal was to serve a small single page JavaScript app on the root of my DropWizard application, while having my DropWizard REST endpoints available at /api. The limited documentation around serving assets in DropWizard suggest that setting up an AssetsBundle for / and changing the application context path in your config file should be enough to achieve this, but that did not work for me. I had to do the following steps:

1. Include the dropwizard-assets Maven dependency.

While the documentation make it appear that the AssetsBundle is part of core DropWizard, it is actually in its own separate dependency. I had to add the following to my pom file:

<dependency>
  <groupId>io.dropwizard</groupId>
  <artifactId>dropwizard-assets</artifactId>
  <version>${dropwizard.version}</version>
</dependency>

2. Add an AssetsBundle to my application.

This is pretty much as described in the documentation. An AssetBundle goes in the initialize method of your DropWizard application and takes three parameters: the path to the assets you want to serve, the path to serve those assets on, and the file to serve by default. My AssetsBundle looked like this:

@Override
public void initialize(Bootstrap<MyConfiguration> myConfigurationBootstrap) {
  ...
  myConfigurationBootstrap.addBundle(new AssetsBundle("/assets", "/", "index.html"));
  ...
}

3. Configure Jersey to serve my resources at /api.

The docs make it appear that you can do this by changing applicationContextPath in your config file, but I didn’t have any luck with that. Instead I had to add line to the run method of my application to set the Jersey URL pattern like so:

@Override
public void run(myConfiguration configuration, Environment environment) throws Exception {
  ...
  environment.jersey().setUrlPattern("/api/*");
  ...
}

With these three steps together, I was able to accomplish what I wanted and serve both my JavaScript app and my REST backend from the same DropWizard application.