Mark, This looks great! Thanks for writing and sharing.
-Matt On Jan 12, 2009, at 11:45 PM, Mark McGranaghan wrote: > > 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 -~----------~----~----~----~------~----~------~--~---