Dropwizard Tutorial – Hello World Example

Dropwizard is an open source Java framework for the rapid development of REST APIs. Dropwizard is kind of ecosystem which contains all the dependencies (such as Jersey, jackson or jetty) bundled into single package or can be added as separate module. If you are not using dropwizard, you will end up collecting all dependencies yourself and it often results into class loading issues due to version mismatch between various java libraries. Dropwizard solve this problem for you, and pulls together stable, mature libraries into a simple, light-weight package that lets you focus on getting things done. Let’s learn to use dropwizard to build REST APIs – step by step.

Table of Contents

Libraries included inside dropwizard
Setup dropwizard with maven
Create REST Application Class
Create REST Resource and APIs
Build Resource Representations
Request Validation
Verify REST APIs
You will need Java 8 to run the examples given in this code which are developed using dropwizard version 1.0.0.

Libraries included inside dropwizard

Once you include dropwizard into your project, you get following libraries added to your classpath.

  • Jersey – For building RESTful web applications.
  • Jetty – Dropwizard uses the Jetty HTTP library to embed an HTTP server directly into your project.
  • Jackson – For object to/from JSON conversion. It allows to export your domain models directly with JAXB annotations.
  • Guava – highly optimized immutable data structures to speedup development.
  • Logback and SLF4j – for performant and flexible logging.
  • Hibernate Validator – an easy declarative framework for validating user input and generating helpful and i18n-friendly error messages.
  • Apache HTTPClient – For both low- and high-level interaction with other web services.
  • JDBI – the most straightforward way to use a relational database with Java.
  • Liquidbase – to keep your database schema in check throughout your development and release cycle.
  • FreeMarker – templating systems.
  • Mustache – simple templating systems for more user-facing applications.
  • Joda Time – very complete and sane library for handling dates and times.

Setup dropwizard with maven

Our project will be based on the maven-archetype-quickstart archetype. You can create the project either using command prompt or use eclipse to create simple maven java project.

mvn archetype:generate -DgroupId=com.howtodoinjava.demo -DartifactId=DropWizardExample 
-DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

Generated project will have pom.xml file as well. Add dropwizard dependency there.

<properties>
	<dropwizard.version>1.0.0</dropwizard.version>
</properties>
<dependencies>
	<dependency>
		<groupId>io.dropwizard</groupId>
		<artifactId>dropwizard-core</artifactId>
		<version>${dropwizard.version}</version>
	</dependency>
</dependencies>

This will download all jar files and add them into your classpath. To add build and package support to our project, we will use the maven-shade plugin, which will allow us to package our project completely, along with its dependencies, into a single standalone JAR file (Fat/Uber JAR) that can be distributed and executed as is.

Complete pom.xml file look like this.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd;
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.howtodoinjava.demo</groupId>
	<artifactId>DropWizardExample</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>DropWizardExample</name>
	<url>http://maven.apache.org</url>

	<properties>
		<dropwizard.version>1.0.0</dropwizard.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<dependency>
			<groupId>io.dropwizard</groupId>
			<artifactId>dropwizard-core</artifactId>
			<version>${dropwizard.version}</version>
		</dependency>
	</dependencies>
	<build>
		<finalName>DropWizardExample-${version}</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-shade-plugin</artifactId>
				<version>2.1</version>
				<executions>
					<execution>
						<phase>package</phase>
						<goals>
							<goal>shade</goal>
						</goals>
						<configuration>
							<transformers>
								<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
									<mainClass>com.howtodoinjava.rest.App</mainClass>
								</transformer>
								<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer">
								</transformer>
							</transformers>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>

</project>

Create REST Application Class

Application class is entry point for any dropwizard application. It needs to extend the io.dropwizard.Application class and implement the initialize(Bootstrap<Configuration>) and run(Configuration, Environment) methods. They prepare the runtime environment of the application.

To invoke the run method, you will need to have public static void main(String[] args) {} method, which will invoked by java -jar command when you run the application as jar file.

package com.howtodoinjava.rest;

import io.dropwizard.Application;
import io.dropwizard.Configuration;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.howtodoinjava.rest.controller.EmployeeRESTController;

public class App extends Application<Configuration> {
	private static final Logger LOGGER = LoggerFactory.getLogger(App.class);

	@Override
	public void initialize(Bootstrap<Configuration> b) {
	}

	@Override
	public void run(Configuration c, Environment e) throws Exception {
		LOGGER.info("Registering REST resources");
		e.jersey().register(new EmployeeRESTController(e.getValidator()));
	}

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

For executing the JAR file, we add the server argument to the command which starts the embedded HTTP Server (Jetty) to run our service.

java -jar target\DropWizardExample.jar server

Dropwizard’s embedded Jetty server will try to bind to ports 8080 and 8081 by default. Port 8080 is used by the server in order to serve incoming HTTP requests to the application, while 8081 is used by Dropwizard’s administration interface.

We have also imported the necessary Logger and LoggerFactory classes in order to construct a Logger instance we could use for our logging needs.

Create REST Resource and APIs

Now when you have added Application bootstrap class, you can now add REST resources containing REST APIs. In this example, I have created and employee management application – so it has APIs for create/update/delete employee records. This class will be responsible for handling HTTP requests and generating JSON responses.

As we have Jersey in our classpath, we will use it to build REST APIs.

package com.howtodoinjava.rest.controller;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import com.howtodoinjava.rest.dao.EmployeeDB;
import com.howtodoinjava.rest.representations.Employee;

@Path("/employees")
@Produces(MediaType.APPLICATION_JSON)
public class EmployeeRESTController {

	private final Validator validator;

	public EmployeeRESTController(Validator validator) {
		this.validator = validator;
	}

	@GET
	public Response getEmployees() {
		return Response.ok(EmployeeDB.getEmployees()).build();
	}

	@GET
	@Path("/{id}")
	public Response getEmployeeById(@PathParam("id") Integer id) {
		Employee employee = EmployeeDB.getEmployee(id);
		if (employee != null)
			return Response.ok(employee).build();
		else
			return Response.status(Status.NOT_FOUND).build();
	}

	@POST
	public Response createEmployee(Employee employee) throws URISyntaxException {
		// validation
		Set<ConstraintViolation<Employee>> violations = validator.validate(employee);
		Employee e = EmployeeDB.getEmployee(employee.getId());
		if (violations.size() > 0) {
			ArrayList<String> validationMessages = new ArrayList<String>();
			for (ConstraintViolation<Employee> violation : violations) {
				validationMessages.add(violation.getPropertyPath().toString() + ": " + violation.getMessage());
			}
			return Response.status(Status.BAD_REQUEST).entity(validationMessages).build();
		}
		if (e != null) {
			EmployeeDB.updateEmployee(employee.getId(), employee);
			return Response.created(new URI("/employees/" + employee.getId()))
					.build();
		} else
			return Response.status(Status.NOT_FOUND).build();
	}

	@PUT
	@Path("/{id}")
	public Response updateEmployeeById(@PathParam("id") Integer id,	Employee employee) {
		// validation
		Set<ConstraintViolation<Employee>> violations = validator.validate(employee);
		Employee e = EmployeeDB.getEmployee(employee.getId());
		if (violations.size() > 0) {
			ArrayList<String> validationMessages = new ArrayList<String>();
			for (ConstraintViolation<Employee> violation : violations) {
				validationMessages.add(violation.getPropertyPath().toString() + ": " + violation.getMessage());
			}
			return Response.status(Status.BAD_REQUEST).entity(validationMessages).build();
		}
		if (e != null) {
			employee.setId(id);
			EmployeeDB.updateEmployee(id, employee);
			return Response.ok(employee).build();
		} else
			return Response.status(Status.NOT_FOUND).build();
	}

	@DELETE
	@Path("/{id}")
	public Response removeEmployeeById(@PathParam("id") Integer id) {
		Employee employee = EmployeeDB.getEmployee(id);
		if (employee != null) {
			EmployeeDB.removeEmployee(id);
			return Response.ok().build();
		} else
			return Response.status(Status.NOT_FOUND).build();
	}
}

For imitating the DB, I have created EmployeeDB class which store employee records and updates in memory.

package com.howtodoinjava.rest.dao;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.howtodoinjava.rest.representations.Employee;

public class EmployeeDB {
	
	public static HashMap<Integer, Employee> employees = new HashMap<>();
	static{
		employees.put(1, new Employee(1, "Lokesh", "Gupta", "India"));
		employees.put(2, new Employee(2, "John", "Gruber", "USA"));
		employees.put(3, new Employee(3, "Melcum", "Marshal", "AUS"));
	}
	
	public static List<Employee> getEmployees(){
		return new ArrayList<Employee>(employees.values());
	}
	
	public static Employee getEmployee(Integer id){
		return employees.get(id);
	}
	
	public static void updateEmployee(Integer id, Employee employee){
		employees.put(id, employee);
	}
	
	public static void removeEmployee(Integer id){
		employees.remove(id);
	}
}

Build Resource Representations

Representation is what holds the data and serialized into JSON. It’s model for RESTful application. When using Jersey with Jackson, all you need to build a resource representation is – a simple POJO following java bean standards. Jackson constructs the JSON string recursively according to the getter methods of each class and their return type.

Any instance of the java.util.List type will be converted to a JSON array.
package com.howtodoinjava.rest.representations;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;

import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;

public class Employee {
	
	@NotNull
	private Integer id;
	@NotBlank @Length(min=2, max=255)
	private String firstName;
	@NotBlank @Length(min=2, max=255)
	private String lastName;
	@Pattern(regexp=".+@.+\\.[a-z]+")
	private String email;
	
	public Employee(){
	}

	public Employee(Integer id, String firstName, String lastName, String email) {
		this.id = id;
		this.firstName = firstName;
		this.lastName = lastName;
		this.email = email;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	@Override
	public String toString() {
		return "Emplyee [id=" + id + ", firstName=" + firstName + ", lastName="
				+ lastName + ", email=" + email + "]";
	}
}

If required in some cases, you can prevent a property from being a part of the JSON representation by adding the @JsonIgnore annotation to its getter.

Request Validation

When accepting PUT and POST requests, you will need to validate user submitted entity content in request body. Dropwizard uses hibernate validator for this purpose. Adding validation requires following steps.

  1. Add validation annotations in representation class

    @NotNull
    private Integer id;
    
    @NotBlank @Length(min=2, max=255)
    private String firstName;
    
    @NotBlank @Length(min=2, max=255)
    private String lastName;
    
    @Pattern(regexp=".+@.+\\.[a-z]+")
    private String email;
  2. Inject Environment.getValidator() in REST resource from Application

  3. @Override
    public void run(Configuration c, Environment e) throws Exception 
    {
    	LOGGER.info("Registering REST resources");
    	e.jersey().register(new EmployeeRESTController(e.getValidator()));
    }
    
  4. Use validator in REST resource

    public class EmployeeRESTController {
    
    	private final Validator validator;
    
    	public EmployeeRESTController(Validator validator) {
    		this.validator = validator;
    	}
    
    	@POST
    	public Response createEmployee(Employee employee) throws URISyntaxException 
    	{
    		Set<ConstraintViolation<Employee>> violations = validator.validate(employee);
    		Employee e = EmployeeDB.getEmployee(employee.getId());
    		if (violations.size() > 0) {
    			ArrayList<String> validationMessages = new ArrayList<String>();
    			for (ConstraintViolation<Employee> violation : violations) {
    				validationMessages.add(violation.getPropertyPath().toString() + ": " + violation.getMessage());
    			}
    			return Response.status(Status.BAD_REQUEST).entity(validationMessages).build();
    		}
    		
    		//Create Employee code here
    	}
    }
    

Verify REST APIs

Now when we have created and added validations for REST APIs, let’s test this out.

Build application uber jar file

> mvn clean package

Start application in jetty server

> java -jar target\DropWizardExample-0.0.1-SNAPSHOT.jar server

Access URI http://localhost:8080/employees

This will return employees collection and related response headers.

Dropwizard - GET Request Example - 1
Dropwizard – GET Request Example – 1

Access URI http://localhost:8080/employees/1

This will return employee’s record with id 1.

Dropwizard - GET Request Example - 2
Dropwizard – GET Request Example – 2

Sent HTTP PUT http://localhost:8080/employees/1 with invalid request data

You will get validation messages.

Dropwizard - Validation Example
Dropwizard – Validation Example

Sent HTTP PUT http://localhost:8080/employees/1 with correct data

Employee record will be updated successfully.

Dropwizard - PUT request Example
Dropwizard – PUT request Example

In same way, you can test other APIs and scenarios.

Let me know your questions in comments section.

Happy Learning !!

Leave a Reply

10 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions, and frequently asked interview questions.

Our Blogs

REST API Tutorial