The JAX-RS layer

If we step back one second and think about which stopover the application will execute, we can identify a few of them:

  • HTTP communication handling
  • Payload (un)marshalling
  • Routing
  • Service invocation

Because of the separation of concern principles, or simply for technical constraints between layers, it is very common to use a Data Transfer Object between the JAX-RS/front layer and the CDI/business layer. Of course, this statement can be applied to the business sub-layers as well, but in the case of this book, we will just do it in the JAX-RS layer. To make it obvious in the book, we will prefix the JAX-RS model with Json. Check out the following code snippet:

@JsonbPropertyOrder({"id", "name", "customerCount"})
public class JsonQuote {
private long id;
private String name;
private double value;

@JsonbProperty("customer_count")
private long customerCount;

// getters/setters
}

In this context, the front layer role is to delegate most of the logic to the service layer and convert the business model to the front model (it can almost be seen as a Java to JavaScript conversion for a lot of modern applications):

@Path("quote")
@RequestScoped
public class QuoteResource {
@Inject
private QuoteService quoteService;

@GET
@Path("{id}")
public JsonQuote findById(@PathParam("id") final long id) {
return quoteService.findById(id) // delegation to the business
layer
.map(quote -> { // the model conversion
final JsonQuote json = new JsonQuote();
json.setId(quote.getId());
json.setName(quote.getName());
json.setValue(quote.getValue());

json.setCustomerCount(ofNullable(quote.getCustomers())
.map(Collection::size).orElse(0));
return json;
})
.orElseThrow(() -> new
WebApplicationException(Response.Status.NO_CONTENT));
}

// other methods
}
We set the JAX-RS @ApplicationPath to  /api to ensure that our endpoints are deployed under the  /api subcontext.