読者です 読者をやめる 読者になる 読者になる

RESTful django, RESTful tropy

Python

ここしばらく、PHPのWebフレームワークを利用して、RESTによるWebサービスを開発することを考えていたのですが、ふと思い立って、djangoを使ってみると、驚くほど簡単に実現できました。


僕は、どちらかというとTurboGearsの方に関心を持っていたので、djangoに関してはIBM DWのチュートリアルを読んだ、という程度の知識しか持っていなかったのですが、それでも、数十分でできてしまいました。


djangoはRESTのために、特別な、気の利いた機能を提供しているわけではありませんが、REST向きの特徴を幾つか持っていて、その一つがdjangoは非常にクリーンで洗練されたURIを生成するということ、もう一つがHTTPプロトコルを扱いやすいということです。
djangoのサーバーAPIは、基本的には、

def some_function(request):
    content = do_some_business_logic()
    return HttpResopnse(content)

というように、HttpRequestオブジェクトを受け取って、HttpResponseオブジェクトを返すというJavaServlet API風のインターフェイスになっています。


最近のWebフレームワークのデザインは、より抽象度の高いモデルクラスやビュークラスを開発者に提供し、こうした抽象度の低いオブジェクトにはアクセスさせないようにするのが主流であるように思われますが、djangoのデザインは、ここではかえって有利に働いています。
この単純なデザインのおかげで、どのように生のPOST, PUTデータにアクセスすればよいのか、フレームワークのどのフローでHTTPステータスコードを送ればよいのか、といったことを悩む必要がなく、次のように、直感的に、簡潔に、書けてしまうわけです。

def handle_put(request):
    # PUTされたデータを取得
    put_data = request.raw_post_data

    # 何らかの処理を行う
    model = do_some_business_logic(put_data)

    # レスポンスボディを用意する。
    # ここではサービスのプロトコルにXMLを使用しています
    response = render_to_response('response.xml', model)
    response['Content-Type'] = 'text/xml'

    # クライントにレスポンスを返します
    return response

ステータスコードを返すのも簡単です。
GETによって要求されたリソースが存在しないならば、

response.status_code = 404

POSTによってリソースが新規作成されたならば、

response.status_code = 201

と実にシンプルな実装を行うことが可能です。


というわけで、先日言及したTropy REST APIをdjangoで実装してみました。サーバー側が

  • GETでランダムなページを取得
  • PUTで取得したページを更新
  • POSTで新規ページを作成

というREST APIを提供し、Javascriptのクライアントがそれを利用しています。


普通のRESTはクライアント側が取得したい情報をURIで示してGETリクエストを送るのでしょうが、このTropy REST APIでは異なります。クライアントは自分の欲しい情報を指定することはできず、どの情報が返ってくるかは分かりません。これがWeb0.5としてのTropyのWeb0.5たる所以です。


ソースコードここからダウンロードできます。


【追記】
taneさんにご指摘いただいて、一部訂正しました。