Should I make my REST client API library Async (Java 8)

1k Views Asked by At

I am creating client libraries for our REST server. For the C# library I use HttpClient.PostAsync() which works great, it returns an object that the caller can just wait on (making it synchronous), they can complete some other actions and then wait, or they can use the C# await mechanism. Great solution.

For Java I have to write the library for Java 8, because that's the version in the largest use. With Java 8 we cover 98% of the programmers out there. (If we get enough demand, I'll do a Java 11 one also and then we have native async calls.)

So here's my question, There are ways to get async behavior, either using DeferredResult or some 3rd party classes. But is there any advantage to my building my API around this and forcing it? Because if I create a synchronous API, the caller can still call it in their own DeferredResult code. Which is the same end result.

So it seems to me the way to provide a simple straightforward API is to deliver a synchronous one. And those that want async wrap it up in whatever mechanism they prefer to make it async. An important advantage here is I don't force a mechanism or 3rd party library they don't use on them.

Is there any downside to this approach?

Update: Here it is in more detail.

If all I have is a synchronous API, then the caller can wrap my synchronous API in many different ways. The easiest using vanilla Java 8 is:

// API is: public Metrics postMetrics(Template template)    
CompletableFuture<Metrics> completableFuture = CompletableFuture.supplyAsync(() -> { return client.postMetrics(template); });

If instead I create an async API, then I am choosing which of these approaches (I would use CompletableFuture) and so the API becomes:

// API is: public CompletableFuture<Metrics> postMetrics(Template template)
CompletableFuture<Metrics> completableFuture = client.postMetricsAsync(template);

Granted, it's a bit easier with that async API. But very little difference. And the downside is I've now forced the async approach on them. Am I missing some larger advantage of providing an async API?

2

There are 2 best solutions below

9
On

It is not the same end result.

Synchronous I/O consumes a lot of memory for blocked threads. This is the main disadvantage of synchronous approach. Making synchronous I/O as primary, your asynchronous I/O still will require synchronous I/O and so will consume a lot of resources.

Rational approach is to make asynchronous interface primary and augment it with synchronous methods. The user then can choose if he can afford to spend memory for blocked threads or to employ multiple I/O operations using minimal resources.

2
On

Perhaps you should think in these terms, what if tomorrow there is another competing library that provides async behavior out of the box and sync as well ?

If I was a developer, I would perhaps choose the one that allows me the async behavior out of the box and also gives me the options to configure it.

What I have said only makes sense if you are thinking in terms of easy developer adoption and inbuilt ease of making async API calls.

I hope this helps.