mercredi 9 novembre 2022

How to transform the CompletableFuture response

Context: I have a client app which consumes an API. I want to call this API is async way (using java.net.http.HttpClient) and once I receive this data then I want to model the response because it can have either error or actual data in java.net.http.HttpResponse<String>. So it will be good if I cloud transform to model class ExecutionResult so that my client app can use this class where ever it wants depending of either error or actual data.

So the API returns CompletableFuture<HttpResponse<String>>:

CompletableFuture<HttpResponse<String>> response = HttpClient.newBuilder()
                .executor(executorService)
                .build()
                .sendAsync(apiRequest, HttpResponse.BodyHandlers.ofString());

Now I want to transform HttpResponse<String> to some another class, lets say ExecutionResult. So basically it should return CompletableFuture<ExecutionResult>

For this, I have written like this but I am not sure this is the correct approach

CompletableFuture<ExecutionResult> fututeExecutionResult = new CompletableFuture<ExecutionResult>();
fututeExecutionResult = CompletableFuture.supplyAsync(new Supplier<ExecutionResult>() {
            @Override
            public ExecutionResult get() {
                ExecutionResult result = null;
                try {
                    HttpResponse<String> httpres = response.get();
                    JsonNode json;
                    try {
                        json = new ObjectMapper().readTree(httpres.body());
                        result = new ExecutionResult(json);
                        if(result.hasError())
                            throw new DataFetchingException(result.getErrorMessage());
                     } catch (IOException e) {
                        e.printStackTrace();
                    }
                } catch (InterruptedException | ExecutionException e1) {
                    e1.printStackTrace();
                } 
                return result;
            }
        });

The model class

  public ExecutionResult(JsonNode response) {
    this.response = response;
    if (response.has(ERROR)) {
        dataFetchingException = new DataFetchingException(getErrorMessage());
    }
}

public boolean hasData() {
    return response.has(DATA) ? Boolean.TRUE : Boolean.FALSE;
}

public JsonNode getData() {
    return response.get(DATA);
}

public boolean hasError() {
    return response.has(ERROR) ? Boolean.TRUE : Boolean.FALSE;
}

public JsonNode getError() {
    return response.get(ERROR);
}

public String getErrorMessage() {
    return response.get(ERROR).findValue(MESSAGE).asText();
}

public DataFetchingException getGraphQLError() {
    return this.dataFetchingException;
}

Could you please suggest any better approach?

Aucun commentaire:

Enregistrer un commentaire