Since you are here you probably already know what thrift is all about. If not take a look at thrift’s apache incubator website. I am writing this because I have not been able to find any step by step tutorial describing how to use thrift with haskell. Let us cut to the chase and get started.
Create greet.thrift
We need a thrift IDL (Interface Definition Language) file. Save the following in greet.thrift:
struct Message {
1: string msg = "default message"
}
service GreetingService {
Message greet(1: Message msg)
}
Generate Haskell Code
To generate haskell bindings for the above IDL file we issue the following command:
thrift -gen hs greet.thrift
The Haskell Server
Save the following in GreetingServer.hs:
module GreetingServer where
import GreetingService_Iface
import GreetingService
import Greet_Types
import Thrift.Server
data GREET = GREET
instance GreetingService_Iface GREET where
greet GREET Nothing = return Message {f_Message_msg = Just "No argument"}
greet GREET (Just m) = return m {f_Message_msg = Just "Reply"}
serve() = runBasicServer GREET process 7911
The Haskell Client
Save the following in GreetingClient.hs:
module GreetingClient where
import Network
import Greet_Types
import GreetingService_Client
import Thrift.Transport.Handle
import Thrift.Protocol.Binary
runclient() = do handle <- hOpen("localhost", PortNumber 7911)
let m = Message {f_Message_msg = Nothing }
result <- greet (BinaryProtocol handle, BinaryProtocol handle) m
print result
Running the Code
Start the server and client from the command line using the following commands:
ghci -fglasgow-exts GreetingServer.hs
ghci -fglasgow-exts GreetingClient.hs
Output
Server
mortenib: gen-hs $ghci -fglasgow-exts GreetingServer.hs
GHCi, version 6.10.4: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
[1 of 4] Compiling Greet_Types ( Greet_Types.hs, interpreted )
[2 of 4] Compiling GreetingService_Iface ( GreetingService_Iface.hs, interpreted )
[3 of 4] Compiling GreetingService ( GreetingService.hs, interpreted )
[4 of 4] Compiling GreetingServer ( GreetingServer.hs, interpreted )
Ok, modules loaded: GreetingServer, Greet_Types, GreetingService, GreetingService_Iface.
*GreetingServer> serve()
Loading package parsec-2.1.0.1 ... linking ... done.
Loading package network-2.2.1.2 ... linking ... done.
Loading package Thrift-0.1.0 ... linking ... done.
Loading package syb ... linking ... done.
Loading package array-0.2.0.0 ... linking ... done.
Loading package containers-0.2.0.1 ... linking ... done.
Client
mortenib: gen-hs $ghci -fglasgow-exts GreetingClient.hs
GHCi, version 6.10.4: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
[1 of 5] Compiling Greet_Types ( Greet_Types.hs, interpreted )
[2 of 5] Compiling GreetingService_Iface ( GreetingService_Iface.hs, interpreted )
[3 of 5] Compiling GreetingService ( GreetingService.hs, interpreted )
[4 of 5] Compiling GreetingService_Client ( GreetingService_Client.hs, interpreted )
[5 of 5] Compiling GreetingClient ( GreetingClient.hs, interpreted )
Ok, modules loaded: GreetingClient, GreetingService_Client, GreetingService, GreetingService_Iface, Greet_Types.
*GreetingClient> runclient()
Loading package parsec-2.1.0.1 ... linking ... done.
Loading package network-2.2.1.2 ... linking ... done.
Loading package Thrift-0.1.0 ... linking ... done.
Loading package syb ... linking ... done.
Loading package array-0.2.0.0 ... linking ... done.
Loading package containers-0.2.0.1 ... linking ... done.
Message {f_Message_msg = Just "Reply"}
*GreetingClient>
Download Files
You can download the above files here.