2011年8月12日金曜日

Webアプリケーションのインタフェース(WSGI, Rack, JSGI, PSGI)

WebアプリケーションのインタフェースxSGI(WSGI, Rack, JSGI, PSGI)のメモ。

Webアプリケーションのインタフェースといっても、いろいろな切り口があるとは思いますが、アプリケーションとサーバー(実行環境)間のインタフェース。PythonのWSGIと、その仲間(Ruby版, Javascript版, Perl版)のこと。シンプルなCGI/Fast CGI/SCGIとも異なるし、古風なxSP系(PHP/ASP/JSP)とも違う感じ。(ここのインタフェースは、それにあわせることで、Webアプリケーションを作る人はいろんなところで動かせる、Webアプリケーション実行環境を作る人はいろいろな人に使ってもらえる、と言うことになります。例えば、WSGIのpythonアプリは、自前のApacheでもクラウドのGoogle App Engineでも、動かせる、みたいな。さらに、中間のフレームワークも、DjangoはWSGIだし、RailsもRackでも。)

1. 簡単なサンプル

text/plainの、Hello Worldを、正常(200)に返す、Webアプリケーションの例(コード断片)。

・WSGI(Python) spec

def application(env, start_response):
  start_response('200 OK', [('Content-type', 'text/plain')])
  return ['Hello world']

・Rack(ruby) spec

class HelloWorldApp
  def call(env)
    [ 200, { 'Content-Type' => 'text/plain' }, ['Hello world'] ]
  end
end

・JSGI(javascript) spec, spec

function(env) {
  return { status : 200, headers : {"Content-Type":"text/plain"}, body : ["Hello world"] };
}

・PSGI(perl) spec

sub {
  my $env = shift;
  return [ '200', [ 'Content-Type' => 'text/plain' ], [ "Hello World" ] ];
};

・PHP版 (ここでは、kelpieの例)

class HelloWorldApp{
    public function call($env){
        return array(200, array("Content-Type" => "text/plain"), array("Hello world"));
    }
}

2. 使い方(入出力)概要

Requestからの入力値(いわゆるGET値/POST値のもとを含む)は、上記の例ではいずれもenv辞書に入っています。
envの中身は、おおむね以下です。
- CGIでもらえそうなもの:REQUEST_METHOD, SCRIPT_NAME, PATH_INFO, QUERY_STRING, SERVER_NAME, SERVER_PORT, HTTP_Variables
- その他:wsgi.version, wsgi.url_scheme, wsgi.input, wsgi.errors, wsgi.multithread, wsgi.multiprocess, wsgi.run_once等(左はWSGIの例で、Rack/JSGI/PSGIなら、wsgi.の代わりに、rack./jsgi./psgi.で始まる名前で)が、入っています。(wsgi.inputを使うと、Requestのbodyにアクセスできます。input streamとしてアクセスできるので大きなRequestに対応できます。)
(いわゆるGET値はQUERY_STRINGから、POST値はwsgi.inputから、求めることになります。)

Response(出力)は、
- Responseのheaderは、ざっと、文字列・文字列の辞書で、返します。
- Responseのbodyは、おおむね、文字列のリストみたいなもので、返します。(受け取った方が、繰り返し(each)、文字列として取り出せるもの。大きなResponseは、それを生成するようなオブジェクトを返す感じでしょうか。)

アプリケーション自体は、
- WSGIでは、a callable object that accepts two arguments.
- Rackでは、an Ruby object (not a class) that responds to call
- JSGIでは、a JavaScript function
- PSGIでは、a Perl code reference. It takes exactly one argument, the environment and returns an array reference of exactly three values.
として作ることになります。

3. 簡単に試す方法

- WSGIをApache + mod_wsgiで試す例は、こちら
- RackをApache + mod_passenger(mod_rack)で試す例は、こちら
- JSGIをJackで試す例は、こちら
- PSGIを試す例は、こちら
- PHP版のWSGIをAppServerで試す例は、こちら

4. 実行環境例

- WebサーバーとCGI/FastCGI
- Webサーバーとmod_*: mod_wsgi, mod_rack(Phusion Passenger)
- uWSGI(uWSGI単体や、uWSGI+Webサーバー)
- それぞれの言語特有のもの WEBRrick, mongrel, ...
- Google App Engine

※ ここで、Webサーバーは、ApacheやNginx, lighttpd等などいろいろ

5. 利用者例など

エンドユーザが自前のアプリを作るのもありですが、各種フレームワークがxSGIにあわせて作られていたりします。
- WSGI(python): Django, web2py
- Rack(ruby): Rails, Sinatra, Redmine

Javascriptも、JSGI 0.3 Adapter for Nodeなんてのもあります。

--
以上

0 件のコメント:

コメントを投稿