Apache Thrift is an open-source software framework that allows developers to build cross-language services. It was originally developed by Facebook and later donated to the Apache Software Foundation in 2007. Thrift enables developers to define data types and service interfaces in a simple language-agnostic Interface Definition Language (IDL). It then generates code for various programming languages, making it easier to implement and consume services across different platforms.
In this article, we’ll explore the core components of Apache Thrift, how it achieves cross-language communication, and walk through a simple example of implementing and consuming a service.
Thrift is composed of several components that work together to enable cross-language communication:
Interface Definition Language (IDL): Thrift uses its own IDL to define data types and service interfaces. The IDL is language-agnostic, allowing developers to define services without being tied to a specific programming language.
Code Generator: Thrift provides a code generator that takes the IDL file as input and generates code in various programming languages. The generated code includes data type definitions, client and server stubs, and serialization logic.
Runtime Libraries: Thrift includes runtime libraries for each supported programming language. These libraries provide the necessary functionality to encode and decode messages, as well as manage client and server communication.
Thrift achieves cross-language communication by using a serialization and deserialization process that supports multiple languages. When a client sends a message to a server, the message is serialized into a binary format, transmitted across the network, and deserialized back into the original data structure by the server. This process is reversed when the server sends a response back to the client.
Thrift supports multiple serialization protocols, such as Binary, Compact, and JSON. Developers can choose the most appropriate protocol based on their needs (e.g., performance, readability).
Let’s walk through a simple example of implementing and consuming a Thrift service. We’ll create a basic calculator service that supports addition and subtraction.
First, we need to define the service interface using the Thrift IDL. Create a file named calculator.thrift
with the following content:
namespace java com.example.calculator
namespace py calculator
service Calculator {
i32 add(1: i32 num1, 2: i32 num2),
i32 subtract(1: i32 num1, 2: i32 num2),
}
This IDL file defines a Calculator
service with two methods: add
and subtract
. The namespace
directive specifies the package name for the generated code in different languages.
Next, use the Thrift code generator to generate code for your target languages. For this example, we’ll generate code for Java and Python:
thrift --gen java calculator.thrift
thrift --gen py calculator.thrift
This will generate the necessary code for both languages in their respective directories (e.g., gen- and
gen-py`).
Now, we’ll implement the server using the generated code. For this example, we’ll create a Java server:
import com.example.calculator.*;
import org.apache.thrift.server.*;
import org.apache.thrift.transport.*;
public class CalculatorServer {
public static class CalculatorHandler implements Calculator.Iface {
@Override
public int add(int num1, int num2) {
return num1 + num2;
}
@Override
public int subtract(int num1, int num2) {
return num1 - num2;
}
}
public static void main(String[] args) {
try {
TServerTransport serverTransport = new TServerSocket(9090);
Calculator.Processor processor = new Calculator.Processor(new CalculatorHandler());
TServer server = new TSimpleServer(new TServer.Args(serverTransport).processor(processor));
System.out.println("Starting the calculator server...");
server.serve();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Finally, we’ll create a Python client to consume the Calculator
service:
from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from calculator import Calculator
try:
transport = TSocket.TSocket("localhost", 9090)
transport = TTransport.TBufferedTransport(transport)
protocol = TBinaryProtocol.TBinaryProtocol(transport)
client = Calculator.Client(protocol)
transport.open()
result = client.add(10, 20)
print(f"10 + 20 = {result}")
result = client.subtract(10, 5)
print(f"10 - 5 = {result}")
transport.close()
except Thrift.TException as tx:
print(f"Thrift exception: {tx.message}")
Now you can run the Java server and Python client to see the cross-language communication in action.
Apache Thrift is a powerful framework for developing cross-language services. By using a language-agnostic IDL, it allows developers to define services without being tied to a specific programming language. Thrift’s code generator and runtime libraries make it easy to implement and consume services across various platforms.
In this article, we explored the core components of Apache Thrift, how it achieves cross-language communication, and walked through a simple example of implementing and consuming a service. With this knowledge, you can start using Thrift to build cross-language services in your own projects.