The Apache Thrift software framework, for scalable cross-language services development, combines a software stack with a code generation engine to build services that work efficiently and seamlessly between C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml and Delphi and other languages.
To get started, download a copy of Thrift.
You will then need to build the Apache Thrift compiler and install it. See the installing Thrift guide for any help with this step.
After the Thrift compiler is installed you will need to create a thrift file. This file is an interface definition made up of thrift types and Services. The services you define in this file are implemented by the server and are called by any clients. The Thrift compiler is used to generate your Thrift File into source code which is used by the different client libraries and the server you write. To generate the source from a thrift file run
thrift --gen <language> <Thrift filename>
The sample tutorial.thrift file used for all the client and server tutorials can be found here.
To learn more about Apache Thrift Read the Whitepaper
Apache Thrift allows you to define data types and service interfaces in a simple definition file. Taking that file as input, the compiler generates code to be used to easily build RPC clients and servers that communicate seamlessly across programming languages. Instead of writing a load of boilerplate code to serialize and transport your objects and invoke remote methods, you can get right down to business.
The following example is a simple service to store user objects for a web front end.
struct UserProfile {
1: i32 uid,
2: string name,
3: string blurb
}
service UserStorage {
void store(1: UserProfile user),
UserProfile retrieve(1: i32 uid)
}
# Make an object
up = UserProfile(uid=1,
name="Test User",
blurb="Thrift is great")
# Talk to a server via TCP sockets, using a binary protocol
transport = TSocket.TSocket("localhost", 9090)
transport.open()
protocol = TBinaryProtocol.TBinaryProtocol(transport)
# Use the service we already defined
service = UserStorage.Client(protocol)
service.store(up)
# Retrieve something as well
up2 = service.retrieve(2)
class UserStorageHandler : virtual public UserStorageIf {
public:
UserStorageHandler() {
// Your initialization goes here
}
void store(const UserProfile& user) {
// Your implementation goes here
printf("store\n");
}
void retrieve(UserProfile& _return, const int32_t uid) {
// Your implementation goes here
printf("retrieve\n");
}
};
int main(int argc, char **argv) {
int port = 9090;
shared_ptr handler(new UserStorageHandler());
shared_ptr processor(new UserStorageProcessor(handler));
shared_ptr serverTransport(new TServerSocket(port));
shared_ptr transportFactory(new TBufferedTransportFactory());
shared_ptr protocolFactory(new TBinaryProtocolFactory());
TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
server.serve();
return 0;
}