Order controller and DTOs

When a request comes to the server to order a bunch of products, it comes in an HTTPS POST request. The body of the request is encoded in JSON. Till now, we had controllers that were handling GET parameters, but handling POST requests is not much more difficult when we can rely on the data marshalling of Spring. The controller code itself is simple:

package packt.java9.by.example.mybusiness.bulkorder.controllers; 

import ...

@RestController
public class OrderController {
private Logger log =
LoggerFactory.getLogger(OrderController.class);
private final Checker checker;

public OrderController(@Autowired Checker checker) {
this.checker = checker;
}

@RequestMapping("/order")
public Confirmation getProductInformation(@RequestBody Order order) {
if (checker.isConsistent(order)) {
return Confirmation.accepted(order);
} else {
return Confirmation.refused(order);
}
}
}

There is only one request that we handle in this controller: order. This is mapped to the URL, /order. The order is automatically converted from JSON to an order object from the request body. This is what the @RequestBody annotation asks Spring to do for us. The functionality of the controller simply checks the consistency of the order. If the order is consistent, then we accept the order; otherwise, we refuse it. The real-life example will also check that the order is not only consistent but also comes from a customer who is eligible for buying those products and that the products are available in the warehouse or, at least, can be delivered, based on the promises and lead time from the producers.

To check the consistency of the order, we need something that does this job for us. As we know that we have to modularize the code and not implement too many things in a single class, we need a checker object. This is provided automatically based on the annotation on the class and also on the constructor of the controller by @Autowired.

The Order class is a simple bean, simply listing the items:

package packt.java9.by.example.mybusiness.bulkorder.dtos; 
import ...;
public class Order {
private String orderId;
private List<OrderItem> items;
private String customerId;

... setters and getters ...
}
The name of the package is dtos, which stands for the plural of Data Transfer Object (DTO). DTOs are objects that are used to transfer data between different components, usually over the network. Since the other side can be implemented in any language, the marshaling can be JSON, XML, or some other format that is capable of delivering nothing but data. These classes do not have real methods. DTOs usually have only fields, setters, and getters.

The following is the class that contains one item in an order:

package packt.java9.by.example.mybusiness.bulkorder.dtos; 

public class OrderItem {
private double amount;
private String unit;
private String productId;

... setters and getters ...
}

The order confirmation is also in this package, and though this is also a true DTO, it has some simple auxiliary methods:

package packt.java9.by.example.mybusiness.bulkorder.dtos; 

public class Confirmation {
private final Order order;
private final boolean accepted;

private Confirmation(Order order, boolean accepted) {
this.order = order;
this.accepted = accepted;
}

public static Confirmation accepted(Order order) {
return new Confirmation(order, true);
}

public static Confirmation refused(Order order) {
return new Confirmation(order, false);
}

public Order getOrder() {
return order;
}

public boolean isAccepted() {
return accepted;
}
}

We provide two factory methods for the class. This is a little violation of the single responsibility principle that purists hate. Most of the time, when the code becomes more complex, such short cuts bite back, and the code has to be refactored to be cleaner. The purist solution would be to create a separate factory class. The use of the factory methods either from this class or from a separated class makes the code of the controller more readable.

The major task we have is the consistency check. The code, till this point, is almost trivial.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.219.63.95