In this article I will discuss about dropwizard , how to implement a simple application using dropwizard.
Dropwizard is a simple tool to develop reliable web applications with minimal maintainance and is easy to learn,implement.
Moving head on to the implementation part ; each dropwizard application must have below components to expose rest api(s):
1. Configurations in yaml format
2. Application configuration (This contains all the configuration files required by your application )
3. POJOs required for data transmission
4. Resource Files to expose your apis
5. Application File
We will be implementing some GET,POST apis using dropwizard to understand the implementation part.Follow up with below steps to create a simple LinkRepository application in Java.
1. Create a new maven project in your favourite IDE.
Below I have added configuration for mysql db and configuration for welcome page
pom.xml
#To connect to mysql db
MysqlDBconfiguration:
host: localhost
port: 3306
username: root
password: dbname: test
#Some other configuration
welcomeConfiguration:
template: Welcome , %s
defaultname: Anonymous
#To start jetty server on port 9000
server:
applicationConnectors: - type: http
port: 9000
adminConnectors: - type: http
port: 9001
2. Next we need to create java configuration classes for each of our configurations to fetch and use the data in the yaml.
Note:To keep your configuration file and class manageable, it is recommended that you group related configuration parameters into independent configuration classes and then plug into the Application Configuration class.
Create a package named configuration with these java files:
DbConfiguration.java
package configuration;
import org.hibernate.validator.constraints.NotEmpty;
public class DbConfiguration {
@NotEmpty
private String host;
private int port;
private String username;
private String password;
private String dbname;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getDbname() {
return dbname;
}
public void setDbname(String dbname) {
this.dbname = dbname;
}
}
WelcomeConfiguration.java
package configuration;
import org.hibernate.validator.constraints.NotEmpty;
public class WelcomeConfiguration {
@NotEmpty
String template;
@NotEmpty
String defaultname;
public String getTemplate() {
return template;
}
public void setTemplate(String template) {
this.template = template;
}
public String getDefaultname() {
return defaultname;
}
public void setDefaultname(String defaultname) {
this.defaultname = defaultname;
}
}
And to bind these configurations
ApplicationConfiguration.java
package configuration;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.dropwizard.Configuration;
public class ApplicationConfiguration extends Configuration {
DbConfiguration dbConfiguration = new DbConfiguration();
WelcomeConfiguration welcomeConfiguration = new WelcomeConfiguration();
@JsonProperty("MysqlDBconfiguration")
public DbConfiguration getDbConfiguration() {
return dbConfiguration;
}
@JsonProperty("MysqlDBconfiguration")
public void setDbConfiguration(DbConfiguration dbConfiguration) {
this.dbConfiguration = dbConfiguration;
}
public WelcomeConfiguration getWelcomeConfiguration() {
return welcomeConfiguration;
}
public void setWelcomeConfiguration(WelcomeConfiguration welcomeConfiguration) {
this.welcomeConfiguration = welcomeConfiguration;
}
}
Note:
1. The @NotNull, @NotEmpty, @Min, @Max, and @Valid annotations are part of Dropwizard Validation functionality. If your YAML configuration file’s field was missing (or was a blank string), Dropwizard would refuse to start and would output an error message describing the issues.
2. Both the getters and setters for template and defaultName are annotated with @JsonProperty, which allows Jackson to both deserialize the properties from a YAML file but also to serialize it.
The mapping from YAML to your application’s Configuration instance is done by Jackson. This means your Configuration class can use all of Jackson’s object-mapping annotations. The validation of @NotEmpty is handled by Hibernate Validator, which has a wide range of built-in constraints for you to use.
WelcomeConfiguration DbConfiguration ...... any other configuration
I
I
I
ApplicationConfiguration
3. Create the POJOs named Link and Welcome ; that we will be using to perform get/post operations in our application. Getters are annotated with @JsonProperty which allows Jackson to serialize and deserialize from JSON. Note that there is empty constructor which is needed for Jackson’s deserialization; this will be particularly required if we want to pass Link as an input to any post api call.
package DTO;
import com.fasterxml.jackson.annotation.JsonProperty;
public class Link {
String url;
String description;
public Link(String url, String description) {
this.url = url;
this.description = description;
}
public Link() {
}
@JsonProperty
public String getUrl() {
return url;
}
@JsonProperty
public void setUrl(String url) {
this.url = url;
}
@JsonProperty
public String getDescription() {
return description;
}
@JsonProperty
public void setDescription(String description) {
this.description = description;
}
}
package DTO;
public class Welcome {
String value;
public Welcome(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
3. Create a resource file ; resource file is where you will actually define your get/post apis
package resources;
import DTO.Link;
import DTO.Welcome;
import app.datastore.LinkDataStore;
import com.codahale.metrics.annotation.Timed;
import com.google.common.base.Optional;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
@Path("/linkrepoapp")
@Produces(MediaType.APPLICATION_JSON)
public class LinkRepositoryResource {
private final String defaultName;
private final String template;
private final LinkDataStore linkDataStore;
public LinkRepositoryResource(String defaultName, String template, LinkDataStore linkDataStore) {
this.defaultName = defaultName;
this.template = template;
this.linkDataStore = linkDataStore;
}
@GET
@Timed
@Path("/welcome")
public Welcome call(@QueryParam("name") Optional<String> name){
final String value = String.format(template, name.or(defaultName));
return new Welcome(value);
}
@GET
@Timed
@Path("/getByUrl")
public Link call(@QueryParam("url") String url){
return linkDataStore.getLinkFromRepo(url);
}
@POST
@Timed
@Path("/save")
@Produces(MediaType.TEXT_PLAIN)
@Consumes({MediaType.APPLICATION_JSON})
public String addLink(Link link) {
linkDataStore.saveLinkInRepo(link.getUrl(), link.getDescription());
return "Stored in database!";
}
}
4. Finally , create an application class. Application class is where you will register all your resources and configurations with jersey.
package app;
import app.datastore.LinkDataStore;
import configurations.ApplicationConfiguration;
import configurations.DbConfiguration;
import configurations.WelcomeConfiguration;
import io.dropwizard.Application;
import io.dropwizard.setup.Environment;
import resources.LinkRepositoryResource;
public class LinkRepositoryApplication extends Application<ApplicationConfiguration>{
@Override
public void run(ApplicationConfiguration applicationConfiguration, Environment environment) throws Exception {
DbConfiguration dbConfiguration = applicationConfiguration.getDbConfiguration();
WelcomeConfiguration welcomeConfiguration = applicationConfiguration.getWelcomeConfiguration();
// Register all configurations with jersey
environment.jersey().register(dbConfiguration);
environment.jersey().register(welcomeConfiguration);
LinkDataStore linkDataStore = new LinkDataStore(dbConfiguration.getHost(), dbConfiguration.getDbname(), dbConfiguration.getPassword(),
dbConfiguration.getUsername(), dbConfiguration.getPort());
// Register all resources with jersey
environment.jersey().register(new LinkRepositoryResource(welcomeConfiguration.getDefaultname(), welcomeConfiguration.getTemplate(),
linkDataStore));
}
public static void main(String[] args) throws Exception {
new LinkRepositoryApplication().run(args);
}
}
Comments
Post a Comment