「あの超大規模サイトであるFacebookがAPI公開の為に作った」というキャッチーなフレーズにひっかかって、Apache Thriftというものを試してみました。EvernoteのAPIもThriftらしいです。
いったいどんな事ができる技術なんでしょうね?
「習うより慣れろ」
ということで、とにかく動かして雰囲気を見てみましょう。
僕もちょっと触ってみただけですが、情報が分散していてわかりにくかったので、自身のメモを兼ねて、動かすまでの手順を書いてみたいと思います。
Apache Thriftってなに?
Thrift自体はいろいろな方がその特長を書かれているのでこちらをどうぞ。
簡単に言えば、
「Java, C++, Python, Ruby…などなど、さまざまな言語で相互にサービスを呼び合う事のできるRPCフレームワーク」
って感じでしょうか?
Thriftが生まれた背景
最近のトレンドとして、WebサービスがAPIを公開するといえば「RESTful」がお約束です。情報の取得、作成、更新、削除をHTTPのGET,POST,PUT,DELETEで行なおうという者です。
そのおかげで、とにかくHTTPさえ叩ければいろんなサービスのAPIを繋いであれこれできちゃう世の中になった訳ですが、問題が無い訳ではありません。
いかに「RESTfulなAPI」といってもすぐに呼び出せる訳ではありません。理由は、HTTPの上を流れるデータフォーマットがサービスによってまちまちな為です。そのため、サービスごとに使用を調べ、パースしたり生成したりするコードを書く必要があります。
そういうところをかっちり決めなくていいところが緩くて嬉しいわけですが、「サービスAは独自のXMLで、サービスBはATOMで、サービスCはJSONで、、、」となっていると、結構大変です。実際には、それぞれのサービス提供事業者がAPIアクセス用のライブラリを提供してくれているので、それをダウンロードしてきて組み込めばよいようになっているのが普通です。
でも、自分が使いたい言語のライブラリを提供してくれているとも限らないのが痛いところ。
「この処理はPythonで書けばあっという間なのに、クライアントライブラリが PerlしかないからPerlで書くか、、、」
といった残念なシチュエーションが生まれている訳です。
そこで出てきたのがThriftです。
「だったらAPIの呼び出しライブラリは自動生成しちゃえば?サーバだって自動生成しちゃうよ。そうすればサービスロジックの作成に専念できるじゃない」
という考え方がThriftの発想です。
ちなみにThriftはHTTPを使いますが、RPCの発想(メソッド呼び出し)なので、いわゆるRESTfulなサービスとは異なる事に注意してください(たぶん)。
Thriftの開発環境をMacOS Xにインストールする
Thriftはコードを自動生成してくれるわけですが、その自動生成用のプログラムをビルドしてインストールする必要があります。ここでは、Thrift-0.6.1をMacOS X 10.6.8にインストールする手順を示します。
Xcodeのインストール
MacOS XにCコンパイラが入っている必要があります。これはAppleから配布されているXcodeを入れれば入ります。入れていない人はまずこれを入れましょう。
MacOS X Lionの人ならばMac App Storeから Xcodeを無料でインストールできます。
boostライブラリのインストール
boostライブラリと言うのはC++で便利にプログラミングする為のライブラリです。これが無いとC++用のコードが生成できないようなので、まずはこれを入れましょう。
http://www.boost.org/ から最新のソースコードをダウンロードしてください。執筆時の最新版は、1.47.0です。ここでは、boost_1_47_0.tar.gzをダウンロードして、適当なフォルダで展開します。
# tar zxvf boost_1_47_0.tar.gz
展開されたディレクトリに移動します。
# cd boost_1_47_0
boostのビルドのお約束コマンド、bootstrap.shを実行しましょう。
# ./bootstrap.sh
すると、カレントディレクトリにb2というコマンドがつくられます。これを実行するとビルドが走ります。
# ./b2
これで終わりではありません、さらにbjamというコマンドを走らせます。
# ./bjam
Performing configuration checks
- has_icu builds : no
warning: Graph library does not contain MPI-based parallel components.
note: to enable them, add "using mpi ;" to your user-config.jam
- ../config//has_gcc_visibility builds : yes
- ../config//has_long_double_support builds : yes
warning: skipping optional Message Passing Interface (MPI) library.
note: to enable MPI support, add "using mpi ;" to user-config.jam.
note: to suppress this message, pass "--without-mpi" to bjam.
note: otherwise, you can safely ignore this message.
こんなメッセージが出て止まってしまいました。指示通り、user-config.jamを修正します。
# vi tools/build/v2/user-config.jam
最後の行に、以下の設定を追加します。
using mpi ;
改めて bjam コマンドでビルドを進めます。
# ./bjam
うまくビルドできたらインストールします。ルート権限が必要なので、sudoを付けるのを忘れずに。
# sudo ./bjam install
Apache Thriftのビルド
Apache Thriftのサイトから最新版(0.6.1)のソースコードをダウンロードしてきて、展開します。
# tar zxvf thrift-0.6.1.tar.gz
中に入って、、
# cd thrift-0.6.1
こんふぃぎゅあー。
# ./configure
2011/9/1 追記。
thrift-0.7.0が出ていたのでビルドしようとしたら configureに実行可能フラグが立っておらず、ビルドできませんでした。どうもアーカイブか壊れている気がします。他のファイルも怪しいです。
install-shも実行可能になってませんね。以下のコマンドで修正してください。
chmod +x configure install-sh
めーく。
# make
あらら、、、
/usr/libexec/gcc/powerpc-apple-darwin10/4.2.1/as: assembler (/usr/bin/../libexec/gcc/darwin/ppc/as or /usr/bin/../local/libexec/gcc/darwin/ppc/as) for architecture ppc not installed Installed assemblers are: /usr/bin/../libexec/gcc/darwin/x86_64/as for architecture x86_64 /usr/bin/../libexec/gcc/darwin/i386/as for architecture i386 src/protocol/fastbinary.c:1203: fatal error: error writing to -: Broken pipe compilation terminated. lipo: can't open input file: /var/folders/n0/n07PPobvF1uOeeW-ljfg8U+++TI/-Tmp-//ccSB6lR0.out (No such file or directory) error: command 'gcc-4.2' failed with exit status 1 make[3]: *** [all-local] Error 1 make[2]: *** [all-recursive] Error 1 make[1]: *** [all-recursive] Error 1 make: *** [all] Error 2 Exit 2
コンパイルが止まってしまいました。ググってみたところ、こんなページが見つかりました。
どうやらXcode4になって、PowerPC用のアセンブラが無くなってしまったらしく、そのせいで止まっているようです。Intel Macなので、Intel用のコードだけ作ってくれれば良いのですが、CPUのアーキテクチャタイプを正しく検出していないためにPowerPCのコードもビルドしようとしているようです。
先ほどのサイトには Thriftのtrunkに対するパッチも提供されているので、次のバージョンくらいではうまくビルドできるようになっているかもしれませんが、当面は以下の対症療法で回避してください。
# cd lib/py # sudo ARCHFLAGS="-arch x86_64" python setup.py install
これがうまく動いたら、Thriftをインストールしましょう。元のディレクトリに戻ってください。
# cd ../.. # make # sudo make install
さて、これで /usr/local/bin あたりに thriftというコマンドがインストールされたはずです。thriftコマンドを起動してみましょう。パスが通っているか確認して実行してみてください。tcshを使っている人はrehashしたりするのを忘れずに、、、。
# thrift
Usage: thrift [options] file
Options:
-version Print the compiler version
-o dir Set the output directory for gen-* packages
(default: current directory)
-I dir Add a directory to the list of directories
searched for include directives
-nowarn Suppress all compiler warnings (BAD!)
-strict Strict compiler warnings on
-v[erbose] Verbose mode
-r[ecurse] Also generate included files
-debug Parse debug trace to stdout
--gen STR Generate code with a dynamically-registered generator.
:
:
こんな感じでヘルプが表示されたら成功です。
Thriftを使ってJavaのコードを生成してみる
僕のメイン言語はJavaなので、ひとまずJavaのコードを生成してみます。木村俊也氏のブログ記事「Thriftが便利すぎる」のインターフェース定義をお借りして、コードを生成してみました。
適当なフォルダに以下の定義ファイルを作成します。
TinyCalc.thrift
#!/usr/bin/thrift
service TinyCalc
{
double sum(1: double param1, 2: double param2)
double subtract(1:double param1, 2:double param2)
}
簡単な足し算と引き算をするサービスです。
この定義ファイルを使ってJavaのコードを生成します。
# thrift --gen java TinyCalc.thrift
実行すると、gen-javaというフォルダが作成され、その中にTinyCalc.javaというファイルが1つ出来ています。実はこのソースコード、これ一つでクライアントサイドとサーバサイドで必要な全てのコードが入っています。中身を見てちょっとびっくりしてしまったんですが、1つのTinyCalcクラスの中に、7個の静的クラスと2つのインターフェースが盛り込まれています!
このクラスを使って実際にRPCの呼び出しをしてみたいと思いますが、ちょっと長くなってきたので、次のエントリで解説します。

Twitter
どうも。
Thriftは以前試したことがあったのですが、詳細はおろか何者かも忘れてました。。
あのときはProtocol Buffersと比較していた気がします。
# 後輩がObjective-Cからサービスを呼びたいとか何とかの経緯で…
最近は徐々にこのあたりに疎くなってきたので、参考にさせていただきます。
ではまた。
コメントありがとうございます!お返事遅くなりました〜。
Google Protocol Buffers、チェックしていませんでした! こちらも面白そうなので、チェックしてみます。