Free Trial

Building Java Microservices with the DropWizard Framework

Dropwizard is an open source Java Framework which was designed to develop high-performing RESTful web services. Dropwizard can be especially useful when building Java microservices. The framework is comprised of tried-and-tested libraries from Java into a single package to enable the developer to focus on developing functionality. The framework provides:

  • Embedded Jetty Server. An HTTP server to run your application.
  • Jersey for Rest and Jackson for JSON
  • Performance metrics and monitoring
  • Google Guava, Logback, Hibernate Validator, Liquibase, Joda Time and many other useful libraries.

To demonstrate how easy it is to get started with Dropwizard, this post walks through the creation of a simple web service. The Dropwizard website has a great getting started example, which creates a Hello World example based on the Maven build system. Let’s go in a different direction, and create a service which returns the shipping cost for a package based on weight. We’ll use Gradle as our build system. The source code for this example can be viewed at https://github.com/echovue/dropwizard_shipping_service.

Bootstrapping the Service

Open your favorite IDE, and create a new Gradle project, I’ll be using IntelliJ Community Edition for this example, but the steps should apply to any editor. Once you have your project created, open the build.gradle file, and add a dependency for the Dropwizard core library. At the time of writing, the current version is 1.1.0. The dependency line to include is: compile(‘io.dropwizard:dropwizard-core:1.1.0’)

java microservices using dropwizard. Dropwizard dependencies which Gradle will add to your project

Dropwizard dependencies that Gradle will add to your project

YAML Configuration—The Secret Sauce

There are two key parts to a Dropwizard-based microservice. A YAML based configuration, and a Configuration class. Let’s first look at the YAML configuration. By convention, this file should be created in the root folder of your application and should be named after the service itself. The file specifies connection specifications for the web service and defines the logging protocols. The file can also be used to define SSL connection properties, and specify the location of metrics collection tools. This example provides additional properties which you may want to include. I’ve named this file shippingservice.yaml.

server:
applicationConnectors:
- type: http
port: 8080
adminConnectors:
- type: http
port: 8081
logging:
level: INFO
loggers:
com.echovue.shippingservice: DEBUG
appenders:
- type: console
- type: file
threshold: INFO
logFormat: "%-6level [%d{HH:mm:ss.SSS}] [%t] %logger{5} - %X{code} %msg %n"
currentLogFilename: /tmp/application.log
archivedLogFilenamePattern: /tmp/application-%d{yyyy-MM-dd}-%i.log.gz
archivedFileCount: 7
timeZone: UTC
maxFileSize: 10MB

Create the Configuration Class

As mentioned previously, the second essential configuration component is the configuration class, which extends the Configuration class. This class is passed into the Application class. If you have specific objects you want to populate for use by your application, this class is a good place to instantiate them, but for our purposes, we’ll leave it in its simplest form. Here’s the ShippingServiceConfiguration Class.

package com.echovue.shippingservice.config;

import io.dropwizard.Configuration;

public class ShippingServiceConfiguration extends Configuration {
}

Create the Application Class

The application class is where our main method lives. This class extends the Dropwizard Application object, and initialized it with the Configuration class we defined previously in the initialize method, which we override.

The run method of the parent class is also overridden, and this is where we declare our various resources and register them with the application. We’re going to instantiate and register the ShippingServiceResource which will be the next class we create.

package com.echovue.shippingservice;

import com.echovue.shippingservice.config.ShippingServiceConfiguration;
import com.echovue.shippingservice.resource.ShippingServiceResource;
import io.dropwizard.Application;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;

public class ShippingServiceApplication extends Application {

public static void main(String[] args) throws Exception {
new ShippingServiceApplication().run(args);
}

@Override
public void initialize(Bootstrap bootstrap) {

}

@Override
public void run(ShippingServiceConfiguration configuration,
Environment environment) throws Exception {
final ShippingServiceResource resource = new ShippingServiceResource();
environment.jersey().register(resource);
}
}

A Simple RESTful Resource

Our resource is created using the Javax.ws.rs package, which contains a collection of interfaces and annotations for the creation of RESTful web services. We’re going to define a get endpoint on the path of “/calculate” which will accept an optional parameter. Shipping package weight. If the weight parameter is present, we’ll create a new ShippingCost object with the weight, and then return the object.

The ShippingCost object contains a very basic cost calculation, and Jackson-based annotations to describe how to render the object in JSON format.

package com.echovue.shippingservice.resource;

import com.codahale.metrics.annotation.Timed;
import com.echovue.shippingservice.model.ShippingCost;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import java.util.Optional;

@Path(“calculate”)
@Produces(MediaType.APPLICATION_JSON)
public class ShippingServiceResource {

public ShippingServiceResource() {}

@GET
@Timed
public ShippingCost calculateShipping(@QueryParam(“weight”) Optional weightOptional) {
if (weightOptional.isPresent()) {
ShippingCost cost = new ShippingCost(weightOptional.get());
return cost;
}
return null;
}
}

ShippingServiceResource Class


package com.echovue.shippingservice.model;

import com.fasterxml.jackson.annotation.JsonProperty;
import org.hibernate.validator.constraints.NotEmpty;

public class ShippingCost {
@NotEmpty
private Double cost;

@NotEmpty
private Double weight;

public ShippingCost() {
}

public ShippingCost(double weight) {
this.weight = weight;
this.cost = 2.35 + (weight * 0.85);
}

@JsonProperty
public Double getCost() {
return cost;
}

@JsonProperty
public Double getWeight() {
return weight;
}
}

ShippingCost Class

Running the Application

So far we’ve created four very basic Java classes and included a single dependency in our build.gradle file. What we have now is a simple but functioning microservice. Let’s get it running.

Depending on your IDE, you may be able to right-click the main function in the Application class and run it as a Java application. If that works, you can skip the rest of this section; otherwise, we’ll briefly cover how to build an executable jar, and run it from the command line.

We’re going to need a few more lines in our build.gradle file to build our jar. There are many ways to accomplish this in Java, but the plugin located at https://github.com/rholder/gradle-one-jar is one of the easiest to implement.

Update your build.gradle file to include the additional plugin definition for ‘gradle-one-jar’, the buildscript section, and the packageJar task. Ensure that the group name at the top of the file, and the mainClass parameter in the packageJar task match the group and main application class for your application.

group 'com.echovue'
version '1.0-SNAPSHOT'

apply plugin: ‘java’
apply plugin: ‘gradle-one-jar’

sourceCompatibility = 1.8

buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath ‘com.github.rholder:gradle-one-jar:1.0.4’
}
}

repositories {
mavenCentral()
}

dependencies {
compile(‘io.dropwizard:dropwizard-core:1.1.0’)
}

task packageJar(type: OneJar) {
mainClass = ‘com.echovue.shippingservice.ShippingServiceApplication’
}

ShippingCost Class

Open a terminal window on your workstation, and execute the following command from the root folder for your project:
Windows
gradlew clean build packageJar
MacOS / Linux
./gradlew clean build packageJar

Gradle will create a jar for the application in build/libs, and also create a fat jar which contains all the dependencies for the application to run. The fat jar will have the suffix of -standalone
To start the application. Run the following command from the root folder of your application:

Windows

java -jar build\libs\shippingservice-1.0-SNAPSHOT-standalone.jar server shippingservice.yaml

MacOS / Linux

java -jar ./build/libs/shippingservice-1.0-SNAPSHOT-standalone.jar server shippingservice.yaml

Open your browser of choice, and navigate to http://localhost:8080/calculate?weight=100.2

The result should be a JSON object similar to:

{
"cost":87.52,
"weight":100.2
}

Resources to Learn More

This simple example shows the ease with which you can create a working microservice using the Dropwizard framework. As stated at the beginning of this article, the biggest benefit to using Dropwizard is the collection of tools and libraries within Dropwizard to provide a framework on which to build your application.

If you would like to know more, the Dropwizard website is an excellent source of examples and documentation to get you started and take your application to the next level. One of the most exciting parts of the framework is the metrics library, which allows you to provide full-stack visibility into your application.

About the Author

Mike Mackrory works by day as a Senior Engineer on a Quality Engineering team and by night he writes, consults on several web based projects and runs a marginally successful eBay sticker business.

Building Java Microservices with the DropWizard Framework is published by the Sumo Logic DevOps Community. If you’d like to learn more or contribute, visit devops.sumologic.com. Also, be sure to check out Sumo Logic Developers for free tools and code that will enable you to monitor and troubleshoot applications from code to production.

Get Started Today!

Sign up for your FREE Sumo Logic Trial.

Free Trial
Sign up for your 30 day free trial!
Sign up for
Sumo Logic Free
  • No credit card required to sign-up
  • Create your account in minutes
  • No expiration date
  • After 30 day trial period, reverts to Sumo Logic Free
    View All Pricing Options Privacy Policy