Build a REST API with Dropwizard
Get started with Java, MySQL, JDBI
Building a REST API can be tedious with all the configuration and library selection. However, I want to introduce Dropwizard, which helps you develop fully functional apps easier and faster.
In this article, we will learn how to create a clean and robust REST API project with Dropwizard, Java, MySQL, JDBI and Docker, step by step.
If you are interested, let’s take the first step together.
Introduction to Dropwizard
Dropwizard is an open source Java framework for developing ops-friendly, high-performance RESTful web services. It can also be described as a set of development tools and frameworks, as Dropwizard contains stable, mature dependencies from the Java ecosystem, allowing you or your team to focus on coding and shipping your project to production.
If we did not use Dropwizard, we would have to install all the libraries required for the project separately and configure each of them ourselves, which often leads to class loading issues due to version mismatches between different Java libraries.
Let’s now take a look at the core libraries that come with Dropwizard by default:
Jetty— an embedded HTTP server directly into our project that runs the app without the need for an external servlet containerJersey— is an implementation ofJAX-RSused as the default framework for building RESTful web applications that expose endpoints and handle HTTP requestsJackson— an object converter for serializing and deserializing Java objects to JSON and vice versaMetrics— a metrics library that provides insight into the performance of an applicationGuava— highly optimized immutable data structures to speed up developmentLogbackandSLF4J— flexible application loggingFreemarkerandMustache— a simple templating system for user-facing applicationsHibernate Validator— a declarative framework for validating user input and generating i18n-friendly error messages based on Bean Validation
Now that you have a general idea of Dropwizard, let’s get some practice!
Setting Up the Project
First, we are going to create a new Dropwizard project where we will create, get, update and delete employees using the REST API. To create the project, we will use Maven and a Maven project template to automatically generate the basic Dropwizard project structure using the following command:
mvn archetype:generate \
-DarchetypeGroupId=io.dropwizard.archetypes \
-DarchetypeArtifactId=java-simple \
-DarchetypeVersion=4.0.12We will then be asked to enter:
name(use camelcase word likeDropwizardExamplein my case as it is used to generate configuration and application classes)groupId(e.g.,io.dropwizard)artifactId(e.g.,dropwizard-example)version(e.g.,1.0-SNAPSHOT)package(e.g.,io.dropwizard)
Great, we have successfully created our Dropwizard app, the project structure usually looks like this:
dropwizard-example/
├── pom.xml
├── config.yml
├── src/
│ └── main/
│ ├── java/
│ │ └── io/
│ │ └── dropwizard/
│ │ ├── api/
│ │ ├── cli/
│ │ ├── client/
│ │ ├── core/
│ │ ├── db/
│ │ ├── health/
│ │ ├── resources/
│ │ ├── DropwizardExampleApplication.java
│ │ ├── DropwizardExampleConfiguration.java
│ └── resources/
│ └── banner.txt
└── README.mdLet’s list the responsibilities of each folder:
api/— request and response objectscli/— CLI commandsclient/— HTTP clients for calling external APIscore/— core app logicdb/— database layer logichealth/— health checkresources/— REST API endpoints
Next, we should add the dropwizard-bom to our pom.xml to consistently manage versions of Dropwizard dependencies throughout the project.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.dropwizard</groupId>
<artifactId>dropwizard-bom</artifactId>
<version>4.0.6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>This will help avoid version inconsistencies by centralized version control.
Modifying the Configuration Class
Each Dropwizard app has its own configurations with specific environment parameters. We will store configurations in a YAML config.yml file in our app root folder which is deserialized to an instance of our app’s configuration class and validated.
This is what our configuration class looks like:
Let’s define our configuration in a config.yml file:
---
logging:
level: INFO
loggers:
io.dropwizard: DEBUG
database:
driverClass: com.mysql.cj.jdbc.Driver
user: root
password: rootpass
url: jdbc:mysql://localhost:3306/mysql-database?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=trueThe DropwizardExampleConfiguration class will be deserialized from the config.yml file into object.
Creating A Representation Class
Now we need to plan our REST API — how we will get and return Employees as a result. Let’s design the JSON format, along with the corresponding representation class that will transform the data into the desired JSON format.
{
"id": 1,
"firstName": "Aidana",
"lastName": "Test",
"email": "test@gmail.com"
}Let’s create a representation class for the above JSON format:
Creating A Resource Class
A resource is the core concept of a RESTful service. Each resource class is associated with a URI template. We will create a resource EmployeeResource class with annotations for request URI mapping and define the URI path using the @Path annotation.
Above we tell Jersey that the EmployeeResource resource is available at the /employees URI using @Path , and returns application/json. Plus this resource provides 5 endpoints:
- GET
/employees— returns a list of employees - GET
/employees/{id}— returns an employee by ID - POST
/employees— creates a new employee by body - PUT
/employees/{id}— updates a specific employee by ID - DELETE
/employees/{id}— deletes a specific employee by ID
Integrating JDBI for Database
Now I am going to use MySQL database and JDBI library to access it. Jdbi is a library that provides convenient access to relational databases in Java and other JVM technologies.
Get Gapur Kassym’s stories in your inbox
Join Medium for free to get updates from this writer.
First, we need to update our pom.xml and install the JDBI and MySQL driver dependencies:
<!-- Dropwizard JDBI3 for database interaction -->
<dependency>
<groupId>io.dropwizard</groupId>
<artifactId>dropwizard-jdbi3</artifactId>
</dependency>
<!-- MySQL Driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.32</version>
</dependency>JDBI allows you to write DAO classes as interfaces, using annotations such as SqlQuery for reading and SqlUpdate for writing data to the database. Let’s define an EmployeeDAO interface for database operations using JDBI:
Awesome, it is pretty simple.
Next, I’m going to create a new EmployeeService as a Service layer that sits between the Resource (controller) and DAO (data access) layers for architectural reasons. This isn’t strictly necessary, but it’s a best practice for maintainability and testability.
Dropwizard Health Check
Health checks give us the ability to add small tests to our app so that we can verify that our app functions correctly in prod. Essentially, we can check the database before we say that our service works by simply retrieving employee data from the database and processing the potential results. We’ll add a health check to make sure we can actually get the list of employees:
Update Application Class
Now we need to update the main application class. This class will gather all the bundles together and launch it for use.
Above we createed a database connection instance, registered our custom health check, and registered the Dropwizard resource.
Running Our Project
Before we start running the app, I’ll set up MySQL in Docker by adding a docker-compose.yml file to the root of the project.
version: '3.9'
services:
database:
image: mysql
container_name: mysql-database
restart: always
ports:
- "3306:3306"
environment:
MYSQL_DATABASE: mysql-database
MYSQL_ROOT_PASSWORD: rootpass
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:This will start a MySQL container with a specified database name and password.
We will use the docker compose command to build the MySQL image:
docker compose buildWait a few seconds, then run:
docker compose upWe should see it listening on port 3306.
Once Docker is properly configured, we can package the app with:
mvn packageWe will see something like this:
Congratulations, we have successfully built our Dropwizard project!
Finally, let’s run Dropwizard app using the following command:
java -jar target/dropwizard-example-1.0-SNAPSHOT.jar server config.ymlTest
To test the app, we can use Postman or any other API client.
Create a new employee
Update employee by id
Get employee by id
Get all employees
Delete employee by id
Conclusion
If you want to check out all of the code, here’s the link to GitHub.
Thanks for reading, I hope you found this piece useful. Happy coding!










