Dropwizard is hot and ready to serve resources so it’s time to create the first HTTP API endpoint and make our app useful. In this post I will prepare endpoint which return random clean code rule.


Dropwizard have many features but the core of this library/framework are resources. Each resource is related with URI and represent some business logic. Our first resource will return random clean code rule instead of classic Hello World.

package com.karollotkowski.cleancode.resources;
import com.codahale.metrics.annotation.Timed;
import com.karollotkowski.cleancode.core.Rule;
import com.karollotkowski.cleancode.repositories.RulesRepository;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
public class RulesResource {
private final RulesRepository rulesRepository;
private final Rule notDefinedRule;
public RulesResource(final RulesRepository rulesRepository) {
this.rulesRepository = rulesRepository;
this.notDefinedRule = new Rule("No title", "No description");
public Rule presentRandomRule() {
return rulesRepository.random().orElse(notDefinedRule);

view raw
hosted with ❤ by GitHub

Annotation @Path(“/rules”) is crucial to provide API endpoint. It tells Jersey (do not mislead with Jersey Shore Massacre) that /rules URI is registered and is associated with methods of this Java class resource.

By adding@Produces(MediaType.APPLICATION_JSON) annotation return data will have JSON format.

Resource constructor has one parameter – clean code rules repository which is a rules storage accessor (will back to this later).

The final and the most important is a presentRandomRule method with @GET annotation. This method will return one random clean code rule or default rule (if no rules defined) when user will call /rules resource via GET HTTP request.

@Timed is an extra (not required) annotation related with Dropwizard metrics module. With this annotation resource method will be added to the metrics statistics in admin panel (I mentioned about Dropwizard admin panel in Run Dropwizard with Gradle).

Clean Code rules

To present data we need an object which represents clean code rule. To do not complicate the example the Rule class contains two fields: title and description.

package com.karollotkowski.cleancode.core;
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.annotation.concurrent.Immutable;
public class Rule {
private String title;
private String description;
public Rule() {
// Jackson deserialization
public Rule(final String title, final String description) {
this.title = title;
this.description = description;
public String getTitle() {
return title;
public String getDescription() {
return description;

view raw
hosted with ❤ by GitHub

Just three remarks here:

  • this class is immutable (important in multithreading environment),
  • each getter should be annotated with @JsonProperty (from Jackson) to provide (de)serialisation from/to JSON,
  • empty constructor is necessary.

Rules will be provided by repositoryRulesRepository. At this moment this repository will have just one method (random) to return random rule from all the defined rules.

package com.karollotkowski.cleancode.repositories;
import com.karollotkowski.cleancode.core.Rule;
import java.util.Optional;
public interface RulesRepository {
Optional<Rule> random();

view raw
hosted with ❤ by GitHub

To make it easy we will read rules from JSON file stored in source resources directory.

"title": "Multiple programming languages",
"description": "Try to keep only one programming language syntax in the source files. Do not mix multiple languages in one file, e.g. Java + HTML."
"title": "Dead code",
"description": "Do not keep unused or commented code. At any time you can back to this code in repository."

view raw
hosted with ❤ by GitHub

And the repository implementation:

package com.karollotkowski.cleancode.repositories;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.karollotkowski.cleancode.core.Rule;
import io.dropwizard.jackson.Jackson;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
public class JsonFileRulesRepository implements RulesRepository {
private static final String RULES_FILE = "rules.json";
private static final ObjectMapper MAPPER = Jackson.newObjectMapper();
private final List<Rule> rules;
public JsonFileRulesRepository() {
rules = fetchRules();
System.out.println("Number of defined rules: " + rules.size());
public Optional<Rule> random() {
return Optional.ofNullable(rules.iterator().next());
private List<Rule> fetchRules() {
final URL rulesResource = getClass().getClassLoader().getResource(RULES_FILE);
try {
return MAPPER.readValue(rulesResource, new TypeReference<ArrayList<Rule>>() {});
} catch (IOException e) {
return Collections.emptyList();

Make it alive!

To start using the new resource we should register it in jersey on application start. Firstly we must to initialise rules repository:

final JsonFileRulesRepository rulesRepository = new JsonFileRulesRepository();

Next initialise rules resource:

final RulesResource rulesResource = new RulesResource(rulesRepository);

and as a final step register resource in environment:


The full Dropwizard application class:

package com.karollotkowski.cleancode;
import com.karollotkowski.cleancode.repositories.JsonFileRulesRepository;
import com.karollotkowski.cleancode.resources.RulesResource;
import io.dropwizard.Application;
import io.dropwizard.setup.Environment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CleanCodeApplication extends Application<AppConfiguration> {
private static final Logger LOGGER = LoggerFactory.getLogger(CleanCodeApplication.class);
public static void main(final String[] args) throws Exception {
new CleanCodeApplication().run(args);
public void run(final AppConfiguration configuration, final Environment environment)
throws Exception {
LOGGER.info("Starting application with name: {}", configuration.getAppName());
final JsonFileRulesRepository rulesRepository = new JsonFileRulesRepository();
final RulesResource rulesResource = new RulesResource(rulesRepository);

After this few lines resource should be available to use. Let’s start application via Gradle run task and open http://localhost:8080/rules endpoint.

Output should be similar to this one:

{"title":"Dead code","description":"Do not keep unused or commented code. At any time you can back to this code in repository."}

Additionally as I mentioned before the new resource method should be added to the metrics in the timers sections:

"timers" : {
    "com.karollotkowski.cleancode.resources.RulesResource.presentRandomRule" : {
      "count" : 2,
      "max" : 0.0046128720000000005,
      "mean" : 0.0023089918465641706,
      "min" : 3.9412E-5,
      "p50" : 3.9412E-5,
      "p75" : 0.0046128720000000005,
      "p95" : 0.0046128720000000005,
      "p98" : 0.0046128720000000005,
      "p99" : 0.0046128720000000005,
      "p999" : 0.0046128720000000005,
      "stddev" : 0.0022866656872260814,
      "m15_rate" : 0.07430150548563609,
      "m1_rate" : 4.326376622914337E-12,
      "m5_rate" : 0.0025637333785025547,
      "mean_rate" : 0.001311739347512153,
      "duration_units" : "seconds",
      "rate_units" : "calls/second"


All the code related with this example you can find on my GitHub profile in this commit.

Happy coding!