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
-~----------~----~----~----~------~----~------~--~---

Reply via email to