Calling a Thrift service
Table of contents
Let's assume we have the following Thrift IDL, served at http://127.0.0.1:8080/hello
, just like what we
used in Running a Thrift service:
namespace java com.example.thrift.hello
service HelloService {
string hello(1:string name)
}
Making a call starts from creating a client:
import com.linecorp.armeria.client.thrift.ThriftClients;
// Use the tbinary format by default.
HelloService.Iface helloService = ThriftClients.newClient(
"http://127.0.0.1:8080/hello",
HelloService.Iface.class); // or AsyncIface.class
String greeting = helloService.hello("Armerian World");
assert greeting.equals("Hello, Armerian World!");
Note that if a serialization format is unspecified, ThriftSerializationFormats.BINARY
is used by
default. You can also specify one of ThriftSerializationFormats.BINARY
,
ThriftSerializationFormats.COMPACT
, ThriftSerializationFormats.JSON
and ThriftSerializationFormats.TEXT
using ThriftClientBuilder.serializationFormat()
.
import com.linecorp.armeria.common.thrift.ThriftSerializationFormats;
HelloService.Iface helloService =
ThriftClient.builder("http://127.0.0.1:8080")
.path("/hello")
.serializationFormat(ThriftSerializationFormats.JSON)
.build(HelloService.Iface.class); // or AsyncIface.class
Since we specified HelloService.Iface
as the client type, ThriftClients.newClient()
will return a
synchronous client implementation. If we specified HelloService.AsyncIface
, the calling code would have looked
like the following:
import com.linecorp.armeria.common.thrift.ThriftFuture;
import com.linecorp.armeria.common.util.CompletionActions;
import com.linecorp.armeria.client.thrift.ThriftClients;
HelloService.AsyncIface helloService =
ThriftClients.newClient("http://127.0.0.1:8080/hello",
HelloService.AsyncIface.class);
ThriftFuture<String> future = new ThriftFuture<String>();
helloService.hello("Armerian World", future);
future.thenAccept(response -> assert response.equals("Hello, Armerian World!"))
.exceptionally(cause -> {
cause.printStackTrace();
return null;
});
// You can also wait until the call is finished.
String reply = future.get();
The example above introduces a new class called ThriftFuture
. It is a subtype of Java 8
CompletableFuture_ that implements Thrift AsyncMethodCallback. Once passed as a callback of an asynchronous
Thrift call, ThriftFuture
will complete itself when the reply is received or the call
fails. You'll find it way more convenient to consume the reply than AsyncMethodCallback thanks to the rich set
of methods provided by CompletableFuture.
You can also use the builder pattern for client construction:
import com.linecorp.armeria.common.HttpRequest;
import com.linecorp.armeria.common.HttpResponse;
HelloService.Iface helloService =
ThriftClients.builder("http://127.0.0.1:8080")
.path("/hello")
.responseTimeoutMillis(10000)
.decorator(LoggingClient.newDecorator())
.build(HelloService.Iface.class); // or AsyncIface.class
String greeting = helloService.hello("Armerian World");
assert greeting.equals("Hello, Armerian World!");
As you might have noticed already, we decorated the client using LoggingClient
, which logs all
requests and responses. You might be interested in decorating a client using other decorators, for example
to gather metrics. Please also refer to ThriftClientBuilder
for more configuration options.