Compojureを使ってみる

Compojureは、Clojure用の小規模なWebアプリ・フレームワークです。

Compojureを使うには、project.cljを次のように変更します。

(defproject helloweb "1.0.0-SNAPSHOT"
  :description "FIXME: write"
  :dependencies [[org.clojure/clojure "1.2.0"]
                 [org.clojure/clojure-contrib "1.2.0"]
                 [compojure "0.5.3"]  ;Webアプリ・フレームワーク
                 [ring/ring "0.3.1"]] ;RingはWebサーバを抽象化した層です。
                                      ;CompojureはRingをベースにしています。
  :main helloweb.core; 実行可能JARを作る場合に指定します。
                     ; helloweb.core/-main がエントリポイントです。
)

core.cljに、Hello Worldのコードを追加します。

(ns helloweb.core (:gen-class)
  (:use compojure.core, ring.adapter.jetty, hiccup.core)
  (:require [compojure.route :as route]))

;アプリケーションのルートを定義します。
(defroutes serve
  ;;(http-method route-path bindings & body)
  (GET "/" [] "<h1>Hello World </h1>")
  (route/not-found "Page not found"))
)

Leiningenを使ってREPLを起動します。

C:\Users\hoge\workspace\helloweb> lein repl 

定義したルートをjettyに渡します。

=> (require 'helloweb.core)
=> (in-ns 'helloweb.core)
=> (run-jetty serve {:port 8080}))

これで、http://localhost:8080 にアクセスすれば、Hello Worldが表示されます。

jettyの起動/停止

run-jettyは、デフォルトでは、REPLをブロックしてしまい不便です。
また、routeの再定義の際にいちいちREPLを再起動するのも面倒です。
(やらずに済む方法があるかも知れませんが、私には分かりません。)

ということで、jettyの起動/停止のコードをcore.cljに追加します。

;;
;;jettyの起動/停止
;;
(defn run [& args]
  "jettyサーバをポート8080で起動します。
   呼出元はブロックされません。"
  (def jetty (run-jetty serve {:port 8080 :join? false})))

(defn destroy []
  "jettyサーバを停止します。"
  (when-not jetty (throw (Exception. "jettyサーバが起動していません。")))
  (doto jetty
    (.stop)
    (.destroy)))

(defn restart [& args]
  "jettyサーバを再起動します。"
  (when jetty (destroy))
  (run args))

起動するときには

(run)

defroutesを変更するときには、REPLでdefroutesを変更してから

(restart)

を実行すれば済むようになります。