This is a practical technology demonstration of many of the features of the Dropwizard REST Framework. It integrates many of the features with common external tools and systems, e.g.
- PostgreSQL
- StatsD/Graphite (https://localhost:8443/)
- Nagios
The service will implement a simple phone book. It demonstrates some basic CRUD operations. The real goal is not the service itself, but to demonstrate a reasonable and fairly robust approach to building a production-ready RESTful HTTP service in Dropwizard.
Additionally, several features and practical approaches of modern Java development will be demonstrated wherever possible.
For example, Maven is an indispensable build tool, test runner, and dependency management system for Java (and really all JVM development). While there are certainly many other newer tools similar to Maven (e.g. Gradle, Ivy, Sbt), Maven is probably the most ubiquitous and also one of the easiest to find answers to questions on StackOverflow ;-).
Before getting started, make sure you have the latest JDK installed, as well as Maven (easily installable via Homebrew).
Now, we can bootstrap a skeleton Dropwizard service quickly using Maven Archetypes. Archetypes are templates for any number of types of projects, there are literally hundreds of them in Maven Central.
mvn archetype:generate \
-DgroupId=com.github.stantonk \
-DartifactId=demo-service \
-Dpackage=com.github.stantonk \
-Dversion=0.0.1-SNAPSHOT \
-DarchetypeArtifactId=java-simple \
-DarchetypeGroupId=io.dropwizard.archetypes \
-DinteractiveMode=false \
-Dname=DemoService
....
This example leverages postgresql, via:
https://wiki.postgresql.org/wiki/PostgreSQL_For_Development_With_Vagrant
vagrant up
psql -h localhost -U demoservice --password -p 15432 -f ./schema.sql
- Run
mvn clean install
to build your application - Start application with
java -jar target/demo-service-0.0.1-SNAPSHOT.jar server config.yml
- To check that your application is running enter url
http://localhost:8080
curl -X POST
-H 'Content-Type: application/json'
-d '{"first_name": "Jenny", "last_name": "Jennerson", "phone_number": "111-867-5309"}'
-vs "http://localhost:8080/api/person"
curl -X GET
-H 'Content-Type: application/json'
-vs "http://localhost:8080/api/person/1"
To see your applications health enter url http://localhost:8081/healthcheck
You get a database and thread deadlock healthcheck out of the box.
For example, this demonstrates:
- The Database Healthcheck
- Recovery upon return of the postgres database
You could, for instance, use the healthcheck to pull an instance of your service out of a load balancer.
$ curl -s "http://localhost:8081/healthcheck" | jqc .
{
"deadlocks": {
"healthy": true
},
"postgresql": {
"healthy": true
}
}
$ vagrant halt
==> default: Attempting graceful shutdown of VM...
$ curl -s "http://localhost:8081/healthcheck" | jqc .
{
"deadlocks": {
"healthy": true
},
"postgresql": {
"healthy": false,
"message": "Unable to successfully check in 3 seconds"
}
}
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
... snip
$ curl -s "http://localhost:8081/healthcheck" | jqc .
{
"deadlocks": {
"healthy": true
},
"postgresql": {
"healthy": true
}
}
TODO:
By using validations, the appropriate HTTP error codes are automatically returned.
E.g. by adding validators to fields on the Person
Representation and
@Validto the
addPerson()` method:
public class Person {
private Long id;
@NotNull
private String firstName;
@NotNull
private String lastName;
@NotNull
private Integer age;
@POST
@Timed
public Person addPerson(@Valid @NotEmpty Person newPerson) {
Person p = personDao.create(newPerson);
logger.info("Created new person {}", p);
return p;
}
A request missing a required Person
attribute gets an HTTP 422 and an
informative, standardized error message:
$ curl -X POST -H 'Content-Type: application/json' -d '{"last_name": "Washington", "age": 284}' -vs "http://localhost:8080/person" | jq .
...
> POST /person HTTP/1.1
...
< HTTP/1.1 422
...
{
"errors": [
"firstName may not be null"
]
}
- healthchecks
- add hikari connection pooling
- load test demonstration with randomness
- graphite/statsd monitoring via GraphiteReporter and Dropwizard-metrics
- admin interface demo
- unit/integration testing examples
- authentication
- more stuff...
https://raw.githubusercontent.com/jackdb/pg-app-dev-vm/master/LICENSE