In my Angular UI, I call an endpoint from API gateway such as:
this.http.post(`/order`).subscribe(order => addNewOrderToList(order));
According to best practise in microservices, the /order
handler should publish an event that to be consumed by one or more microservices, instead of calling each other using synchronous REST. So, I write the following handler:
@RequestMapping
public Future<Order> addOrder() {
CompletableFuture<Order> future = new CompletableFuture<>();
// publish event
// ...
// wait for final event raised by a service.
future.complete(createdOrder);
return future;
}
From the perspective of the UI, isn't that user will not see the new order until my endpoint returned a new order? I feel like the UI is still synchronous even when the backend is asynchronous. What is the best practice to improve the UI in this case?
Perhaps what you should do is to embrace asyncrony and eventual consistency in this case.
Your HTTP endpoint, when invoked, actually does nothing, it only accepts the UI command, and enqueues it for other backend microservices to eventually process it, right?
So, what you probably should do is just accept the command, validate it, enqueue it and just return a HTTP status code 202 Accepted to the client. You could include an ETA header in your response indicating more or less when the client can poll another endpoint to check if the results are ready. If you're following a truly RESTful approach, you may include the link to the resource the client can use to poll the results when ready.
You may want to read the following articles: