Application boundaries

The applications of a CQRS system communicate via events internally. Externally, other protocols such as HTTP can be provided.

The query and command functionality of, for example, the waiter system, is exposed via JAX-RS. The command service offers functionality to place meal orders. It uses the event producer to publish the resulting events:

public class OrderService {

    @Inject
    EventProducer eventProducer;

    public void orderMeal(OrderInfo orderInfo) {
        eventProducer.publish(new OrderPlaced(orderInfo));
    }

    void cancelOrder(UUID orderId, String reason) {
        eventProducer.publish(new OrderCancelled(orderId, reason));
    }

    void startOrder(UUID orderId) {
        eventProducer.publish(new OrderStarted(orderId));
    }

    void deliverMeal(UUID orderId) {
        eventProducer.publish(new MealDelivered(orderId));
    }
}

The orderMeal() method is called by the HTTP endpoint. The other methods are called by the waiter system's event handler. They will result in new events that are delivered by the event hub.

The reason for not directly firing events or calling functionality internally here is that this application resides in a distributed environment. There might be other instances of the waiter system consuming the event hub and updating their representation accordingly.

The command service contains a JAX-RS resource that is used to order meals:

@Path("orders")
public class OrdersResource {

    @Inject
    OrderService orderService;

    @Context
    UriInfo uriInfo;

    @POST
    public Response orderMeal(JsonObject order) {
        OrderInfo orderInfo = createOrderInfo(order);
        orderService.orderMeal(orderInfo);

        URI uri = uriInfo...

        return Response.accepted().header(HttpHeaders.LOCATION, uri).build();
    }

    ...
}

The query service exposes the meal order representations. It loads the current state of the domain entities from the database as seen in the MealOrders. The JAX-RS resources of the query service use this functionality.

If the waiter system is shipped as a single instance, containing both the command and query services, these resources can be combined. It needs to be ensured though that the services don't cross-communicate, except via the eventing mechanism. The following code snippet shows the query service endpoint:

@Path("orders")
public class OrdersResource {

    @Inject
    MealOrders mealOrders;

    @GET
    @Path("{id}")
    public JsonObject getOrder(@PathParam("id") UUID orderId) {
        MealOrder order = mealOrders.get(orderId);

        if (order == null)
            throw new NotFoundException();

        // create JSON response
        return Json.createObjectBuilder()...
    }
}

These examples are not exhaustive, but are meant to give the reader an idea of integrating CQRS concepts and message hubs into Java EE applications.

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

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