Dropwizard als REST-App-Server

Verwaltung und REST

Anzeige

Um den fiktiven Online-Shop in Betrieb zu nehmen, müssen sich zum einen die Bestellungen intern verwalten lassen und zum anderen ist eine REST-Schnittstelle für die Bestellungen nötig. Zudem sollte der Shop einen Report zum aktuellen Bestellstand erzeugen können. Ideal wäre hier sowohl eine Webschnittstelle als auch ein Report via REST und JSON für externe Systeme.

Die interne Verwaltung setzt die Klasse OrderManagement um, die die Bestellungen der Einfachheit halber in einer Map verwaltet. Sie implementiert zudem Dropwizards Managed-Interface. Es erlaubt Klassen, sich in den Lebenszyklus einer Dropwizard-Anwendung einzuhängen, indem es die beiden Methoden start() und stop() implementiert. Dropwizard startet via start() alle registrierten Managed-Implementierungen, bevor eingehende Requests akzeptiert werden, und stoppt sie, wenn die Anwendung keine neuen mehr entgegennimmt. Mittels Managed lassen sich so Initialisierungen durchführen, die für die Anwendung zwingend erforderlich sind. Externe Systeme, wie Message-Queues, lassen sich so anbinden.

public class OrderManagement implements Managed
{
private final OrderLimit orderLimit;
private boolean isRunning;

private List<Order> orders = new ArrayList<>();

public OrderManagement(OrderLimit limit) {
orderLimit = limit;
}

@Override
public void start() throws Exception {
isRunning = true;
}

@Override
public void stop() throws Exception {
isRunning = false;
}

public boolean processOrder(Order order) {
boolean accepted = false;

if (orderLimit.isInLimit(order.getAmount())) {
orders.add(order);

accepted = true;
}

return accepted;
}

public List<Order> getOrders() {
return orders;
}
}

Die Implementierung der REST-Schnittstellen für den Empfang von Bestellungen erfolgt durch eine typische REST-Ressource aus JAX-RS, deren einziges Dropwizard-Spezifikum die @Timed-Annotation ist, um Performance-Metriken zu erheben.

@Path("/order")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class OrderResource {
private final OrderManagement orderManagement;

public OrderResource(OrderManagement management) {
orderManagement = management;
}

@POST @Timed
public OrderAffirmation processOrder(@Valid Order order)
{
OrderAffirmation affirmation = new OrderAffirmation();
affirmation.setBrand(order.getBrand());
affirmation.setCustomer(order.getCustomer());

boolean accepted = orderManagement.processOrder(order);

affirmation.setAccepted(accepted);
affirmation.setAmount(order.getAmount());

return affirmation;
}
}

Bedingt durch die Annotation @Valid am Order-Parameter der Methode [/i]processOrder()[/i], validiert Dropwizard mit Hibernate Validator das aus dem eingehenden Request erzeugte Order-Objekt, dessen Annotationen unter anderem sicherstellen, dass es keine negativen Bestellmengen oder fehlende Angaben zum Besteller gibt. Nur bei erfolgreicher Validierung ruft die Anwendung processOrder() auf, andernfalls erzeugt sie aus dem verletzten Bean-Validation-Constraint eine für den Nutzer verständliche Fehlermeldung und liefert sie zurück.

Das Erzeugen einer Bestellübersicht via REST und JSON erfolgt wieder als normale JAX-RS-REST-Ressource:

@Path("/orderreport")
public class OrderReportResource
{
private final OrderManagement orderManagement;

public OrderReportResource(OrderManagement management) {
orderManagement = management;
}

@GET @Produces(MediaType.APPLICATION_JSON) @Timed
public java.util.Map<String, Long> getReport() {
OrderReport report = new OrderReport();

for (Order order : orderManagement.getOrders()) {
report.addOrder(order);
}

return report.getAmountPerBrand();
}

@GET @Produces(MediaType.TEXT_HTML) @Timed
public OrderReportView getView() {
OrderReport report = new OrderReport();

for (Order order : orderManagement.getOrders()) {
report.addOrder(order);
}

return new OrderReportView(report);
}
}
Anzeige