Skip to content Skip to sidebar Skip to footer

Decoupled Design For Async Http Request

What i am trying to write is a view-> controller -> model -> client -> HttpRequestSender relationship that is abstract, so i can replace the HttpRequestSender when i am

Solution 1:

When you want to compose computations that may involve a lot of asynchronous steps, there aren't any really good options that will let you write super-clean code.

Of the options that are available -- event-driven design, continuation passing, monads, etc., monads are the modern choice, because they let you write asynchronous code that has the same basic structure as the equivalent synchronous code. It's still won't be very pretty code, but at least it's built of the same functional blocks.

In JavaScript the asynchronous monad is Promise, and in Java it's CompletionStage/CompletableFuture. This is what your class looks like in that style (I'm assuming all the calls to client are async and return a CompletionStage):

DeviceClient client;

DeviceInfoMgr deviceInfoMgr;

public CompletionStage<Void> registerDevice(String name) {

    return checkIfNameTaken(name)
        .thenCompose( (unused) -> client.createDevice())
        .thenCompose(deviceResponse -> {
            Device device = deviceResponse.getBody();
            device.setName(name);
            return client.updateDevice(device);
        }).thenApply(unused -> {
            deviceInfoMgr.set(name);
            return (Void)null;
        });
}

private CompletionStage<Void> checkIfNameTaken(String name) {

    return client.getAllDevices()
        .thenCompose(devices -> {

            for(Device dev : devices) {
                if(dev.getName() == name) {
                    //I use a helper for this
                    CompletableFuture<Void> err = new CompletableFuture<>();
                    err.completeExceptionally(new DeviceNameTakenException());
                    return err;
                }
            }
            return CompletableFuture.completedFuture((Void)null);
        });
}

You see that it has the same methods that it had before, and those methods do the same thing they did before, and they do it with the same sequence of operations... but now they return a CompletionStage, indicating that they may run asynchronously and the results may depend on things that aren't done when those methods return.

Post a Comment for "Decoupled Design For Async Http Request"