2008/01/23

Factor : Web アプリケーション

Writing Web Applications in Factor を参考に Factor で Web アプリを書いてみました。とりあえずは Hello World レベルですが。

まず、Web サーバ自体は httpd ワードで起動します。USE: http.server 8883 httpd で 8883 番ポートで Web サーバが動きます。
単に httpd だとリスナに戻ってこないので、[ 8883 httpd ] in-thread として別プロセスで起動します。

Factor の Web フレームワークは Furnace というのがあるようです。
extra/webapps の下に pastebin[ planet-factor ] のソースがあります。

Furnace で注意しなければならないのが、URL、ボキャブラリ名、Web アプリケーション名の関係です。
URL は http://localhost:8883/responder/Webアプリケーション名/アクション名 という形式になります。
ボキャブラリ名は webapps.ボキャブラリ名 というように webapps の下の階層にしなければなりません(ソースファイルの場所は関係ありません)。
Web アプリケーション名は web-app ワードでデフォルトアクション名、テンプレートパス名と一緒に指定します。


http://localhost:8883/responder/hello-furnace/
IN: webapps.hello-furnace
"hello-furnace" "hello" "." web-app


それともう一つテンプレートパスも注意が必要です。
デフォルトでは Furnace の内部で resource-path が使われているので、Factor のソースコードロケーションからの相対パスになってしまいます。
アクションワードの中で resource-path を実際のテンプレートファイルがあるパスに設定しなおす必要があります(もっといい方法があるかもしれませんが)。
Factor の変数はダイナミックスコープです。そのためアクションの外で resource-path を設定すると、その設定がグローバルに影響をおよぼして、他のものが動かなくなってしいます。
Common Lisp っぽいですね。

アクションの定義はふつうにワードを定義した後、そのワードシンボルで define-action するだけです。
ほんのさわりだけですが Factor らしくシンプルで好きです。
hello-furnace.factor
USING: io furnace http.server.responders html
http.server io.files threads namespaces ;

! Furnace は webapps 以下のボキャブラリでなければならない。
! hello の部分は web-app で指定する name と一致しなければらなない。
IN: webapps.hello-furnace

[ 8883 httpd ] in-thread

! テンプレートファイルのあるパスを resource-path に設定する。
: res-path ( -- )
home "letter/factor/try/webapp" path+ \ resource-path set ;

! text/plain でレスポンスするアクション
: text ( -- )
serving-text "Text action." print ;

! これでアクションを定義
\ text { } define-action

! テンプレートファイルを読み取って text/html でレスポンスするアクション
: hello ( -- )
res-path ! resource-path を設定する
serving-html
[ "hello-furnace" render-template ] ! hello-furnace.furnace という
with-html-stream ; ! テンプレートファイルでレスポンスする。

! これでアクションを定義
\ hello { } define-action


! Web アプリケーション名, デフォルトアクション, テンプレートファイルの
! あるパス を指定して responder を作成する。
"hello-furnace" "hello" "." web-app

hello-furnace.furnace
<% USING: furnace namespaces io ; %>
<html>
<head>
<title>Hello Furnace</title>
</head>

<body>
<h1>Hello Furnace</h1>

<% "Factor で遊ぼう♪" write %>

<hr>
<a href="text">Text アクション</a>
</body>
</html>

0 件のコメント: