ClojureでWebアプリを作ってみよう

CompojureというClojureでWebアプリケーションを開発するためのフレームワークを使って簡単なエコーアプリケーションを作ってみました。
ちなみにCompojureはRubySinatraというフレームワークにインスパイアされて開発されたものだそうです。残念なことにSinatraは名前は聞いたことがありますが、一度も触ったことがないので「ふーん、そうなんだー」という感じです。
まずはCompojureのセットアップから。
CompojureはGitHubで開発されています。CompojureのサイトにはLeiningenでセットアップする方法が解説されていますが、ここではソースからビルドする方法を紹介します。
以下のページからソースをcloneするなり、ダウンロードページからアーカイブを落としてきて適当な場所に展開します。

依存するJARファイルは以下のようにAnt(ソースに付属するbuild.xmlのdepsターゲット)で落とせるようになっています。deps.zipというZIPファイルがダウンロードされ、depsディレクトリに展開されます。

> ant deps

続いてCompojure自体をビルドします。

> ant jar

compojure.jarというJARファイルができるので、先ほどダウンロードした依存JARファイルとまとめてクラスパスを通してREPLを起動するためのバッチファイルを作っておきましょう。

java -cp .;^
compojure.jar;^
deps/commons-io-1.4.jar;^
deps/commons-fileupload-1.2.1.jar;^
deps/commons-codec-1.3.jar;^
deps/clojure.jar;^
deps/clojure-contrib.jar;^
deps/jetty-6.1.15.jar;^
deps/jetty-util-6.1.15.jar;^
deps/servlet-api-2.5-20081211.jar clojure.main

続いてエコーアプリケーションです。カレントディレクトリに以下の内容でsample.cljというファイルを作成します。

(ns sample)
(use 'compojure)

(defn input-form []
  (html (form-to [:post "/"]
    (text-field {:name "name"} "")
    (submit-button "Send"))))

(defn say-hello [name]
  (html [:h1 (format "Hello %s!" (escape-html name))]))

(defroutes sample-app
  (GET  "/" (input-form))
  (POST "/" (say-hello (params :name)))
  (ANY  "*" (page-not-found)))

さきほど作成したバッチファイルでREPLを起動し、以下のようにしてサーバを起動します。

user=> (use 'sample)
nil
user=> (compojure/run-server {:port 8080} "/*" (compojure/servlet sample-app))
2010-05-04 22:44:09.671::INFO:  Logging to STDERR via org.mortbay.log.StdErrLog
clojure.proxy.javax.servlet.http.HttpServlet
2010-05-04 22:44:09.687::INFO:  jetty-6.1.15
2010-05-04 22:44:09.734::INFO:  Started SocketConnector@0.0.0.0:8080
#<Server Server@14c4d61>

起動したらWebブラウザでhttp://localhost:8080/にアクセスしてみましょう。エコーアプリケーションの動作を確認できるはずです。
ちなみにsample.cljを修正した場合は以下のようにREPLでリロードを行うことですぐに修正を反映させることができます。

user=> (use :reload 'sample)
nil

と、まあこんなところでClojureでWebアプリケーションを作るための準備が整いました。