2011年6月30日木曜日

05.What a service is made of

ProtoRPCの一つのサービスは、複数のリモートメソッドを定義した、一つのPythonクラスによって定義します。

それぞれのリモートメソッドは、リクエストを受け取り、レスポンスを返します。
リクエストとレスポンスはともに、messages.Messageを継承した、ユーザー定義のクラスです。

04.Defining a service

Google App Engineの、GettingStartedGuideで、ゲストブックアプリケーションを作成しました。

ゲストブックアプリケーションは、典型的なwebアプリケーションで、
サイト訪問者は、メッセージを記入することができ、
また、他の訪問者が記入したメッセージの閲覧ができます。

ゲストブックアプリケーションは、
アプリケーションとユーザーが直接対話する、という前提で書かれています。

このため、ゲストブックアプリケーションは、他のwebアプリケーションが、簡単にゲストブックアプリケーションの情報にアクセスして、それを利用できるようなインターフェイスを公開していません。

例えば、ゲストブックアプリケーションに投稿されたメッセージの日時から、
1日あたりの投稿数のグラフを出力するようなアプリケーションを作成したい場合などです。

03.Installation

ProtoRPCは、まだ開発の初期段階です。
現在、ProtoRPCを使ってみる、一番手っ取り早い方法は、Google App Engineを使うことです。

<protorpc-source-dir>/python/protorpc を、アプリケーションディレクトリにコピーするか、
eclipseを使っている場合は外部参照のライブラリに追加してください。

ただし、SDKのバージョンは1.5.1以上を使ってください。
それより古いと、sdkのディレクトリに、ProtoRPC関係のファイルはありません。

02.Helloサンプル

次のコードは、ProtoRPCで定義された、簡単なRPCサービスの例です。

from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
from protorpc import messages
from protorpc import remote
from protorpc.webapp import service_handlers
class HelloRequest(messages.Message):
  my_name = messages.StringField(1, required=True)
class HelloResponse(messages.Message):
  hello = messages.StringField(1, required=True)
class HelloService(remote.Service):
  
  @remote.method(HelloRequest, HelloResponse)
  def hello(self, request):
    return HelloResponse(hello='Hello there, %s!' %
                         request.my_name)
service_mappings = service_handlers.service_mapping(
    [('/hello', HelloService),
    ])
application = webapp.WSGIApplication(service_mappings)
def main():
  util.run_wsgi_app(application)
if __name__ == '__main__':
  main()
 この簡単なサービスは、クライアントから、ユーザーの名前を受け取ります。(HelloRequest.my_name)
そして、そのユーザーに対する挨拶メッセージを返します。
(HelloResponse.hello)

注目して欲しいのは、これがサーバー側で書かなければならないコードのすべてであり、
PythonからJSONに変換したり、HTTPリクエストハンドラを書く必要はない、ということです。

次に、JQueryを使って、javascriptからこのサービスを使う方法を示します。


  $.ajax({url: ‘/hello.hello’,
          type: 'POST',
          contentType: 'application/json',
          data: ‘{ my_name: Bob }’,
          dataType: 'json',
          success: function(response) {
            // The response is { hello: “Hello there, Bob!” }
            alert(response.hello);
          }
         });
このコードは、サーバーにリクエストをJSONで送り、サーバーはレスポンスをJSONで返します。
ProtoRPCのメッセージ型は、よく使われるデータ型に対応していますので、
JQueryのsuccessハンドラを使うことで、簡単にjavascriptオブジェクトに変換できます。

01.導入

ProtoRPCは、webベースのRPC(Remote Procedure Call)サービスを簡潔に定義する方法です。

RPCサービスとは、リモート呼び出し可能なメソッドと、メソッドが受け取ったり返したりするメッセージ型の集まりであり、
それらを用いることにより、クライアントアプリケーションがwebアプリケーションと通信することを可能にします。

さて、実際に自分でこのようなwebベースのRPCを、
クライアント:javascript
サーバー:Python
という環境で定義する場面を想定してみてください。

サーバー側では、各メソッドに相当するURLを定義し、リクエストを受け取った際に、パラメータのチェックを行い、Pythonのオブジェクトに変換する必要があります。
クライアント側では、ユーザーの入力チェックを行い、入力データをHTTPリクエストのパラメータに変換します。
そしてサーバーからの返答をjavascriptオブジェクトに戻す必要があります。

このような変換まわりのコードは、毎回同じようなコードになる上に、
くだらない間違いにイライラさせられることが多いです。

ProtoRPCは、この種の変換を、異なるプログラム言語間であっても簡単に行えるようにしたライブラリです。
ProtoRPCは、サーバー側で、リモートメソッドやメッセージ型をPythonオブジェクトとして定義できるようにしました。

Pythonだけを用いて、RPCの定義ができますので、
独自のRPCの作成が容易になるはずです。