0

We have to make a bunch of HTTP calls from Java/Spring-Boot application which will be mix of in-sequence and parallel.

Level 1 : We make 3 parallel calls to Services 1 , 2 and 3

Level 2: After service 1 response is received (which is a list), we make parallel calls to service 4 and 5 for each item in list

Level 3 : After service 5 response is received, depending on its response, we make parallel calls to Service 6 for few of items received from service 1.

Which design pattern should be used? Will the Command design pattern would be a good use case here?

I was thinking, may be we create a DataProvider having 2 properties isParallel and httpService. And then I ccreate objects of DataProvider and set these 2 attributes for each of the HTTP call we want to make. Does it make sense?

asked May 11, 2021 at 4:21
3
  • 2
    Does this answer your question? Choosing the right Design Pattern Commented May 11, 2021 at 4:22
  • Thanks @gnat for pointing me to this question. Though, it doesn't exactly answers my question but it points in the right direction. Commented May 11, 2021 at 4:26
  • 1
    It sounds like a pipeline to me. Commented May 11, 2021 at 7:46

2 Answers 2

3

What you're maybe looking for is simply "async programming" or non-blocking programming. The default tool to use in Java for that is CompletableFuture, unless you are using a different tool explicitly (like reactive libraries, or akka, etc.)

Technically that boils down to:

  1. Converting all network calls to return CompletableFuture, for those that do not already do that. Like calls that use callbacks, or return some 3rd party objects for futures.
  2. Then composing these calls in the appropriate manner.

Like:

// Level 1: 3 services in parallel
CompletableFuture.allOf(service1(), service2(), service3());
// Level 2: Make parallel calls to 4 and 5
public CompletableFuture<?> service1() {
 // After calling service 1, call 4 and 5 in parallel with results
 return callService1().thenCompose(items ->
 CompletableFuture.allOf(service4(items), service5(items)));
}
// Level 3: Call service 6 conditionally
public CompletableFuture<?> service5(List<Item> items) {
 return callService5(items).thenCompose(response -> {
 if (response.isSomething()) {
 return callService6(items);
 } else {
 return CompletableFuture.completedFuture(null); // No-op
 }
 });
}

That's about it. Of course this is not a real design, it's just the rough technical steps involved, but seeing how it's done might help to imagine a design for it.

answered May 11, 2021 at 10:56
1
  • Thanks for the answer. I will definitely try this out and will try to post the implementation in few days for others' benefit. Commented May 11, 2021 at 11:29
1

Classing example of orchestration flow. Orchestration flow most of the time utilizes Command pattern very well along with Aggregator. But like in the link @gnat provided, Patterns are prescribed solution to a specific software design problem. Identifying problem is most important in choice of design pattern.

answered May 19, 2021 at 20:26

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.