Service interface design

We design the two interfaces that we will implement. When we design interfaces, we focus on the functionality first. Formatting and protocol come later. Interfaces generally should be simple and, at the same time, should accommodate the future change. This is a hard problem because we cannot see the future. Business, logistics, and all other experts may see some part of the future: how the world will change and what it will impose on the operation of the company and, especially, on the interface we provide for our partners.

The stability of an interface is of utmost importance because the partners are outside entities. We cannot refactor the code they use. When we change a Java interface in our code, the compiler will complain at all the code locations where the change should be followed. In case of an interface that is used outside of our realm, this is not the case. Even if it is only a Java interface that we publish as open source on GitHub, we should be prepared that our users will face issues if we change the library in an incompatible way. In that case, their software will not compile and work with our library. In the case of an ordering system, it means that they will not order from us and we will soon be out of business.

This is one of the reasons why interfaces should be simple. Although this is generally true for most of the things in life, it is extremely important for such interfaces. It is tempting to provide convenience features for the partners because they are easy to implement. In the long run, however, these features may become very expensive as they need maintenance, should be kept backward compatible, and, in the long run, may not gain as much as they cost.

To access product information, we need two functions. One of them lists certain products and another returns the details of a specific product. If it were a Java API, it would look as follows:

List<ProductId> query(String query); 
ProductInformation byId(ProductId id);

Similarly, order placement may look as shown in the following:

OrderId placeOrder(Order order);

We provide these functionalities in our application via a web service interface and, more specifically, REST using JSON. We will discuss these technologies in a bit more detailed manner along with the Spring framework and Model View Controller design pattern, but first let's look at the product information controller to get some feeling of how our program will look:

package packt.java9.by.example.mybusiness.productinformation; 

import ...

@RestController
public class ProductInformationController {

@Autowired
ProductLookup lookup;

@RequestMapping("/pi/{productId}")
public ProductInformation
getProductInformation(@PathVariable String productId) {
ProductInformation productInformation =
lookup.byId(productId);
return productInformation;
}

@RequestMapping("/query/{query}")
public List<String> lookupProductByTitle(@PathVariable String query, HttpServletRequest request) {
//to be developed later
}
}

If you compare the code of the servlet with the preceding code, you can see that this is much simpler. We do not need to deal with the HttpServletRequest object, call an API to get a parameter, or create an HTML output and write it to the response. The framework does this. We annotate the @RestController class, telling Spring that this is a controller that utilizes the REST web services; thus, it will by default create a JSON response from the object we return. We do not need to care about the conversion of the object to JSON, although we can if there is really a need. The object will automatically be converted to JSON using the field names used in the class and the field values of the instance we return. If the object contains more complex structures than just plain String, int, and double values, then the converter is prepared for nested structures and the most common data types.

To have different code handling and different URLs on the servlet, all we need to do is to annotate the method with @RequestMapping, providing the path part of the URL. The {productId} notation inside the mapping string is readable and easy to maintain. Spring just cuts the value from there and puts it for us in the productId variable, as requested by the @PathVariable annotation.

The actual lookup of the product is not implemented in the controller. That is not the function of the controller. The controller only decides what business logic to invoke and what view to use. A part of it is implemented in the framework, and the very small part you can see the preceding code. The business logic is implemented in a service class. An instance of this class is injected to the lookup field. This is also done by Spring. The actual work we have to do is to invoke the business logic, which this time, since we have only one, is fairly easy.

Most of these things seem magic without some more details about what the framework does for us. Therefore, before going on, we will have a look at the building blocks: JSON, REST, MVC, and a bit of the Spring framework.

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

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