AFAIK: there's no "rails" or "django"-like framework written in clojure. And that's OK.
Here's Why
To me, a web framework provides…
Ring is a lib that specifies the http abstraction(it's just a map) and provides some useful middleware for working with that abstraction(more later)
{:ssl-client-cert nil, :remote-addr "0:0:0:0:0:0:0:1", :scheme :http, :request-method :get, :query-string "qs=1", :content-type nil, :uri "/test/path/", :server-name "localhost", :headers {"accept-encoding" "gzip,deflate,sdch", "connection" "keep-alive", "user-agent" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36", "accept-language" "en-US,en;q=0.8", "accept" "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "host" "localhost:3000", "cookie" ""}, :content-length nil, :server-port 3000, :character-encoding nil, :body #<HttpInput org.eclipse.jetty.server.HttpInput@43efe432>}
{:headers {"Content-Type" "text/plain"}, :status 200, :body "hello world"}
(defn hello-app [request] {:status 200 :body "hello world"})
(ns hello (:require [ring.adapter.jetty :as jetty])) (defn hello-app [request] {:status 200 :body "hello world"}) (defn -main [] ;; Run the server on port 3000 (jetty/run-jetty handler {:port 3000}))
Compojure can provide routing to functions that is more in line with what we have come to expect from a web framework
(defroutes app-handler (GET "/api/artists/:artist-id/albums/:album-id/tracks/:track-id" [artist-id album-id track-id] (track-detail artist-id album-id track-id)) (POST "/api/mounts" [new-mount] (add-new-mount new-mount)) (DELETE "/api/mounts" [mount] (delete-mount mount)) (POST "/api/do-scan" [] (do-scan)) (GET "/index.html" [] (render-to-response (page))) (GET "/" [] {:status 302 :headers {"Location" "/index.html"}})) (def app (-> app-handler (wrap-params) (j/wrap-json-response) (m/wrap-resource "public") (wrap-not-modified) (wrap-content-type) (wrap-gzip) (wrap-partial-content)))
session db connection cache/memoize