0

Currently I'm working on creating something with the following general structure. I want to call 4 different APIs in sequential order (the results of one are needed for the next one). If one throws an exception, undo the efforts of the previous APIs with their sister delete APIs.

Currently my structure/ control flow looks like:

boolean A = false;
boolean B = false;
boolean C = false;
boolean D = false;
string response = StringUtils.EMPTY

try {
   API_A;
   A = true;
}
catch (A's Exceptions {
    response = "fail!"
}

if (boolean_A == false){
   undo_if_stuff_to_undo;
   return response;
}

Basically this repeated 3 times and if all 4 were successful my response would say success. I was wondering if there was a cleaner way to approach this. I thought about making a function for each API call that returned a boolean but the problem was that I needed the results from each API to call the next. Perhaps creating a special class for each API result that would store its success/failure and relevant attributes?

1

... I thought about making a function for each API call that returned a boolean but the problem was that I needed the results from each API to call the next...

Then don't use a boolean; use an Optional<T>. That way, you test for success of each function with result.IsPresent() and rollback if not.

So you can then create functions that wrap the try/catch logic for each API and return an empty optional for a failure and an optional with the result for a success and chain them together as you describe.

  • Ah I see so for each API helper funciton I create its just java private Optional<T> apiAhelper(....) return null if catches exception return response object if it works well – PLfan666 Feb 6 at 19:23
  • @PLfan666, exactly. – David Arno Feb 6 at 20:12
  • And then I just put my response object in the Optional yea? So if API A returns an API_A_Response object itd be Optional<API_A_Response> ? – PLfan666 Feb 7 at 3:03
2

To me, it looks like the case for try-with-resource pattern. As your A, B, etc do not implement the AutoCloseable, you could do something like (I don't know java very well so may write something wrong):

abstract class WithRollback<T> : AutoCloseable {
 // fields instead of properties here for shortness
 public bool if_rollback;
 public T data;
 public WithRollback(T data) { this.data = data; this.if_rollback = true; }
 public void close() { if (this.if_rollback) { this.rollback(this.data); } }
 abstract void rollback(T);
}

try (
 resA = new WithRollback<A>(makeA;) { void rollback(A data) {undoA;} };
 resB = new WithRollback<B>(makeB;) { void rollback(B data) {undoB;} };
 resC = new WithRollback<C>(makeC;) { void rollback(C data) {undoC;} };
 resD = new WithRollback<D>(makeD;) { void rollback(D data) {undoD;} }
) {
 resA.if_rollback = false;
 resB.if_rollback = false;
 resC.if_rollback = false;
 resD.if_rollback = false;
}

so that exiting the scope with perform rollback until you mark all of the successful

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.