Hi All, I'm happy to announce the alpha release of 'Ring', a library inspired by Python's WSGI and Ruby's Rack for developing web applications in Clojure.
I've made it as easy as humanly possible for you to try it out: git clone git://github.com/mmcgrana/ring.git cd ring java -Djava.ext.dirs=jars clojure.main src/ring/examples/ hello_world.clj And your up and running with your first Ring web app, which you can see at http://localhost:8080/ in your browser. The basic idea of Ring is that web apps are just Clojure functions that take a standardized request as a single argument and return and standardized response. For example, the hello_world.clj script from above is: (ns ring.examples.hello-world (:require ring.jetty) (:import java.util.Date java.text.SimpleDateFormat)) (def formatter (SimpleDateFormat. "HH:mm:ss")); (defn app [req] {:status 200 :headers {"Content-Type" "text/html"} :body (str "<h3>Hello World from Ring</h3>" "<p>The current time is " (.format formatter (Date.)) ".</p>")}) (ring.jetty/run {:port 8080} app) Its nice to be able to get to "Hello World" so quickly, but the real power of Ring is that apps are just functions - hence we can combine, wrap, curry, and generally manipulate them as first class values. For example, someone asked in #clojure today how they could make their web app provide a cleaned backtrace as an HTML response when it raised exceptions. To add such exception handling to our Hello World Ring app we would just use the ring.backtrace middleware: (ring.jetty/run {:port 8080} app) becomes (ring.jetty/run {:port 8080} (ring.backtrace/wrap app)) Similarly, one might want to have changes to a web app's code be reflected in real time in the development environment, so as to avoid constantly having to reboot the webserver. The ring.reload middleware accomplishes exactly that: (ring.jetty/run {:port 8080} (ring.backtrace/wrap (ring.reload/wrap '(ring.examples.hello-world) app) These are some of the features that originally motivated me to develop Ring, but the complete list of functionality available to Ring apps is larger and continues to grow: * ring.jetty: Handler for the Jetty webserver. * ring.file: Middleware that serves static files out of a public directory. * ring.file-info: Middleware that augments response headers with info about File responses. * ring.dump: Endpoint that dumps the Ring requests as HTML responses for debugging. * ring.show-exceptions: Middleware that catches exceptions and displays readable backtraces for debugging. * ring.reload: Middleware to automatically reload selected libs before each requests, minimizing server restarts. * ring.builder: Helpers for combining Ring endpoints and middleware into Ring apps. * ring.lint: Linter for the Ring interface, ensures compliance with the Ring spec. * ring.examples.*: Various example Ring apps. You can find more details about Ring at its project page on GitHub, including a README file for new users and a draft SPEC file that documents the Ring interface: http://github.com/mmcgrana/ring I've built an open source web app on Ring: http://cljre.com. The source for this simple app, available at http://github.com/mmcgrana/cljre.com, could serve as a good introduction to how apps can consume Ring requests and to the use of modular Ring middleware; see in particular the src/cljre/app.clj file, where most of that application is defined. Also, I think I should mention how I see Ring relating to the Java Servlet abstraction and to existing and new Clojure web frameworks. Ring heavily leverages the Servlet API internally, as I strongly believe in not reinventing wheels such as basic HTTP parsing. Furthermore, I think that the interface that Ring presents to Clojure web application developers by pre-processing the servlet requests is dramatically more useful than that of the raw servlet. Ring uses Servlets for what they are really good at - implementing HTTP - and presents a simple API against which additional logic can be defined in the application layer. In terms of Clojure web frameworks, I think that there is a lot to be gained by leveraging the Ring interface, especially from the modular functionality provided by Ring middleware. I'd like in particular to be able to run Compojure apps in Ring - if the users and authors of Compojure are interested I'd be happy to work with them to see what we can do. If you've made it this far, thanks a lot for reading! I welcome any comments or suggestions that you have about Ring, the draft SPEC document, or the Clojure web app space in general. Thanks again, - Mark --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---