【Delphi Sample】Delphi と Google App Engine と Thrift と Java その1
【Delphi Sample】Delphi と Google App Engine と Thrift と Java その1
皆さんはサーバーとクライアントの通信にどのような方法を利用していますか?
この記事では、クライアントアプリケーションをDelphi
、サーバーアプリケーションをGoogle App Engine (GAE/J)
にて実装し、その間の通信には Apache Thrift
を利用するサンプルを紹介します。
キーワード
実際のサンプルに入る前に主要なテクノロジーやソフトウエアについて少し触れてみます。
-
- Google App Engine
- Google が運営するPaaSです。サーバーのことをほとんど意識することなく、アプリケーション開発に集中できます。制限もありますが、特性を理解して適切に使うことができれば、ほかの環境では簡単に作成することができないアプリケーションを作ることができます。
-
- Delphi
- デルファイと読みます。Pascal言語を利用してアプリケーションを作ることができる開発環境です。フレームワークがとても強力で、多様なプラットフォームをサポートしています。GUIアプリケーションを作るうえで、これだけ安定している環境は得難いのではないでしょうか?
-
- Thrift
- スリフトと読みます。アプリケーション間で処理の呼び出しをサポートしてくれるフレームワークです。これを利用するとクライアントアプリケーションからサーバーアプリケーションの関数を呼び出すことができます。この類のテクノロジーはいくつも出ていましたが、使い勝手や保守性に優れており、特別な技術が使われているわけでもなくとてもシンプルに作られています。
そのシンプルさゆえ、いろいろな言語で利用することができます。同じ言語間の通信はもちろん、今回のようにJava
とDelphi
など異なる言語間でも通信を行うことができます。
インターフェイスを決める
サーバーとクライアントの間で何かやり取りをするということは、やり取りの方法を決める必要があります。具体的には、データと処理の呼出し口を決めます。
インターフェイスをしっかりと決めておくことで、以下のような利点があります。
- サーバーとクライアントで分業できる。
- インターフェイスを見るだけで、アプリケーションの全体像がつかめる。
JSONやXMLを使ってデータのやり取りを行うのがよく使われる方法ですが、インターフェイスを決める主導権はどちらか一方に偏りがちです。サーバー側での変更がクライアント側に伝わらず、いつの間にかデータ構造が変わっていたということもあるのではないでしょうか?
この問題をThrift
はインターフェイス記述言語(IDL)というもので解決しています。つまり、インターフェイスそのものをコーディングするという考え方です。コーディングできるということはソースコード管理を行うことができますから、いつの間にか変わってしまったという現象を防ぐことができるのです。
インターフェイス設計
今回は四則演算のサービスを作成します。インターフェイスのコーディングにはIDLを利用します。Thrift
専用の言語ですが、覚えることも少ないのでドキュメントを眺めながら進めていけばすぐに慣れると思います。
クラスにメソッドを宣言していくようなつもりで進めていくのがいいでしょう。JSONやXMLでのやり取りではデータが中心となってきますから、アプローチの方法が異なりますね。
ここで行うのはあくまでもインターフェイスの設計・宣言です。実装については誰が行ってくれるかというと、そこはThrift
が担ってくれます。つまり、ソースコードはThrift
が自動生成してくれるわけです。
calculator.thrift
計算サービスを定義していきます。コメントをつけたので、理解しやすいのではないでしょうか?namespace
を宣言するとグルーピングが行えます。ここではJavaとDelphiでグルーピング方法を変えています。細かく分割するのか、一つにまとめてしまうかは言語の作法に従うのがいいと思います。
また、include
を使って、ほかのIDL
ファイルを読み込むこともできます。
もう一つ注目してもらいたいのは、exception
で例外を定義しているということです。今回の四則演算のサービスでは、割り算でゼロ除算を行ったときに例外を送出するよう考えています。言語間で例外をやり取りできるのは表現の幅が広がりますね。
namespace java com.example.thrift
namespace delphi ThriftInterface.Calculator
include "common.thrift"
/** 計算サービス */
service CalculatorService {
/** 加算 */
i32 add(1:i32 param1, 2:i32 param2),
/** 減算 */
i32 sub(1:i32 param1, 2:i32 param2),
/** 乗算 */
i32 mul(1:i32 param1, 2:i32 param2),
/** 除算 */
i32 div(1:i32 param1, 2:i32 param2) throws (1: common.TInvalidParameterException error)
}
common.thrift
calculator.thrift
で利用した例外はこちらで宣言しています。後でサービスを追加することを想定して、ファイルを分けています。
namespace java com.example.thrift
namespace delphi ThriftInterface.Common
/** パラメータに誤りがあったときの例外 */
exception TInvalidParameterException {
1: string message
}
ファイルの自動生成
Windowsを利用している人はここから実行ファイルをダウンロードしてください。コマンドラインプログラムなので、適当な場所に配置し、その場所をPathに追加すると使いやすいです。
Macを利用している人はBrewを使って実行ファイルをセットアップしてください。
今回は2つのthrift
ファイルを作成したので、次のようにコマンドを実行します。common.thrift
は参照されているので、初めに実行します。
rmdir /s /q gen-java
rmdir /s /q gen-delphi
thrift --gen java --gen delphi IDL/common.thrift
thrift --gen java --gen delphi IDL/calculator.thrift
コード生成の前にgen-java
gen-delphi
のフォルダを削除するコマンドを入れておくと、間違いが少なくなりますね。
フォルダ構成
gen-java
とgen-delphi
という二つのフォルダができています。中にはそれぞれJava
のソースファイルとDelphi
のUnit
が生成されているのが分かるでしょうか?
namespace
の宣言によってフォルダ構成やファイルの分かれ方も変わってきます。いろいろと試してみてください。
コメント
コメントを投稿