Dropwizard is a framework for building RESTful web services in Java. In this tutorial we're going to have a look at how to get started with developing a Dropwizard application by building a new service from scratch. This article is going to cover the very basics. The goal is to implement and run a Dropwizard application which is able to respond to an HTTP GET request.
After a short introduction to Dropwizard and our application domain, we will see how to create a new project, talk about its structure, and configure it. Later on we will implement a simple RESTful API before finally building and running your application.
The sample project is available on GitHub. Key commits are tagged and I'll be referencing them throughout this post after each major change. If you feel that something is unclear and wish to see a snapshot of the whole project, feel free to check out the referenced tag.
The only prerequisites you need to have installed are Maven, JDK, and a text editor or IDE of your choice.
[author_more]
What is Dropwizard?
As already stated, Dropwizard is a framework for building RESTful web services in Java. In essence, it is a glue framework which bundles together popular and battle-tested Java libraries and frameworks to make it easier to start building new RESTful web services.
Here's an incomplete list of some of the libraries that Dropwizard uses.
- Jersey - reference implementation of JAX-RS, the API for RESTful web services in the Java platform
- Jackson - library for processing JSON data
- Jetty - HTTP server and Java Servlet container
- Metrics - library for capturing JVM- and application-level metrics for monitoring
- Guava - utility library
- Logback - logging library
Introducing Our Demo Application Domain
To get a better understanding of Dropwizard, we're going to build a RESTful web service from the ground up. It is going to be a back-end for a hypothetical events app. Imagine you've moved to a new city and would like to plan your evening. This app will list events based on your search criteria and location. The back-end should be able to provide a list of events. It should also be possible to add new events and update existing events. To keep things simple, we're going to exclude user authentication and authorization for now.
Project Structure
I'm going to use Maven as a build tool. In my opinion, the easiest way to get started with a new application is to create a project using the dropwizard-archetype
. Archetype is essentially a tool for bootstrapping a Maven project from a template.
Run the following command in your terminal to get started with a new Dropwizard project.
mvn archetype:generate \
-DarchetypeGroupId=io.dropwizard.archetypes \
-DarchetypeArtifactId=java-simple \
-DarchetypeVersion=1.0.2
As of October 2016, the latest version of Dropwizard is 1.0.2. Be sure to check the most recent version and update archetypeVersion
accordingly. Running the archetype:generate
command prompts you to enter some project specific fields (e.g. groupId, artifactId). When entering the project name, keep in mind that this field is used to generate application and configuration classes. Use CamelCase and do not insert spaces to make sure that the generated class names are going to be valid.
For example, I named the application Events. Therefore the generated classes are going to be named EventsApplication
and EventsConfiguration
. If I had used events-app as the name, event-appApplication
and event-appConfiguration
would have been generated. Unfortunately, these are invalid class names and the compiler will point that out to you.
On successful completion, This is what the generated folder structure looks like.
.
├── config.yml
├── pom.xml
├── README.md
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── mydomain
│ │ ├── api
│ │ ├── cli
│ │ ├── client
│ │ ├── core
│ │ ├── db
│ │ ├── EventsApplication.java
│ │ ├── EventsConfiguration.java
│ │ ├── health
│ │ └── resources
│ └── resources
│ ├── assets
│ └── banner.txt
└── test
├── java
│ └── com
│ └── mydomain
│ ├── api
│ ├── client
│ ├── core
│ ├── db
│ └── resources
└── resources
└── fixtures
Application configuration is stored in config.yml
. We're going to look at it in more detail in the next paragraph. Most of the meat is located in src/main/java
including the two aforementioned classes - EventsApplication
and EventsConfiguration
.
The following is an overview of which files should go into which folder:
api
- Here live your application representations, which are essentially the entities of your API. They are serialized and deserialized to JSON.
cli
- Contains commands that can be executed from the command line. They are not covered in this tutorial.
client
- HTTP client implementation of your API. For easy consumption of your API you can implement a client and place it here. We're not going to do it in this tutorial.
core
- This is where you implement your domain logic.
db
- Classes related to database access.
health
- Contains health checks. These are runtime tests which verify whether your application is behaving correctly.
resources
- Jersey resources.
We're not going to use all of these packages since I'd like to keep the tutorial on the easier side. Dropwizard isn't strict about the package naming scheme. If you wish you can rename and restructure the package hierarchy to suit your needs better.
The initial project structure can be seen by checking out the starting-point
tag.
[caption id="attachment_141062" align="alignnone" width="1024"] Published by Jared Tarbell under CC-BY 2.0[/caption]
Application Configuration
Storing variables which might vary depending on the execution environment in a configuration file is considered to be a good practice. When running your application, Dropwizard expects to receive a configuration file as a command line argument. By default configuration files should be written in YAML. The parsed configuration fields are used to build a new instance of a configuration class.
For now, let's keep the configuration file as straightforward as possible. There are two things I would like add. Firstly, let's change the root path of our application so all REST endpoints will be served from /api/*
. The rootPath
parameter is one of many built-in configuration parameters Dropwizard has to offer, so we do not need to change any code to have it available.
Secondly, since we're dealing with events, we care about the start time, which can be represented in many ways. Let's add a date format configuration parameter, which enables us to control the output date format from a configuration file.
First, modify config.yml
and add the following configuration.
server:
rootPath: /api/*
dateFormat: yyyy-MM-dd'T'HH:mmZ
Of course we need to access the custom configuration parameter dateFormat
from within the running application. When Dropwizard is started, configuration fields are mapped to a configuration class' member fields.
So let's edit our configuration class and include the dateFormat
field. Open EventsConfiguration
and add the following lines:
@NotEmpty
private String dateFormat;
public String getDateFormat() {
return dateFormat;
}
An application shouldn't trust an external configuration file to be correct. To help validate its correctness, we can use Hibernate Validator. The @NotEmpty
annotation makes sure the string is not empty. Otherwise Dropwizard fails to start.
Keep in mind that this does not check if the date format pattern is actually valid. It only checks if it is defined in the configuration file. You could create your own custom validator which will print out a nice error message at start-up if the pattern is invalid. To keep things simpler, I'm not going to tackle this issue at the moment.
Check out app-configuration
tag to see the project after configuration changes.
Application Class
This is what the generated application class looks like.
public class EventsApplication extends Application<EventsConfiguration> {
public static void main(final String[] args) throws Exception {
new EventsApplication().run(args);
}
@Override
public void run(EventsConfiguration configuration, Environment environment) {
}
@Override
public void initialize(Bootstrap<EventsConfiguration> bootstrap) {
}
}
When starting the service, the main
method inside the EventsApplication
class gets invoked. This is the entry point for a Dropwizard application. A new EventsApplication
object is created and its run
method is called. The run
method is used to configure Dropwizard's environment.
This is the place to apply the date pattern used in our application. For that we configure Jackson's ObjectMapper
, which will later (de)serialize the request and response parameters from Java classes to JSON and vice versa. Let's modify its date format by explicitly creating a new instance of SimpleDateFormat
and passing it the pattern from the configuration object.
@Override
public void run(EventsConfiguration configuration, Environment environment) {
DateFormat eventDateFormat = new SimpleDateFormat(configuration.getDateFormat())
environment.getObjectMapper().setDateFormat(eventDateFormat);
}
Later we're going to modify the run
method to register new resources.
The application class has one more method we need to look at although we're not going to add any code inside it: initialize
is used to go through the application’s bootstrapping phase. Here you can add bundles and commands for example. Bundles are groups of reusable functionality - think of them as add-ons to your application. Commands can be used to create additional functionality that can be accessed from the command line.
Checkout date-format-configuration
tag to see the project after changes made in the application class.
Creating a Representation of Domain Objects
Representations are the entities of your API. They represent the current or the desired state of a resource. For example, when a client makes an HTTP GET request to the events resource, the server sends back a representation of the current state of events. Representations can be serialized to any format but we're going to use JSON in this tutorial.
Let's think about what fields we want to include in the events representation class. An event should have a name. Also, we need to know when and where the event is taking place. Hosts might want to add additional information about the event. This calls for a description field. It is a good idea to include an id as well since we want to make sure each event is uniquely identifiable.
Continue reading %Getting Started with Dropwizard%
by Indrek Ots via SitePoint