Clack - Web Application Environment for Common Lisp

Clack is a Web Application Environment for Common Lisp inspired by Python's WSGI and Ruby's Rack. Your awesome framework should base on this.

Usage

(defpackage simple-app
  (:use :cl
        :clack))
(in-package :simple-app)

(clackup
  #'(lambda (req)
      '(200 (:content-type "text/plain") ("Hello, Clack!"))))

Now access http://localhost:5000/ and Clack may show you "Hello, Clack!".

Installation

Clack is now available on Quicklisp.

(ql:quickload :clack)

Application

Clack Application is just a lambda. It takes exactly one argument, the "Request", and returns the "Response" as a list containing exactly three values.

(defvar app
  #'(lambda (req)
      '(200 (:content-type "text/plain") ("Hello, World"))))

Clack.App.Route

Clack is not a Web Application Framework. But Clack can also be used as such way.

Clack bundles "Clack.App.Route", written by Tomohiro Matsuyama. It allows you to write an URL-based dispatcher, like Ruby's Sinatra.

(defroutes app (req)
  (GET \"/\" #'index)
  (GET \"/login\" #'login)
  (POST \"/login\" #'authorize)
  (GET \"/member/:id\" #'member))

(clackup #'app)

The Request

Example: http://localhost:4242/sns/member?id=3

(:request-method :GET
 :script-name ""
 :path-info "/sns/member"
 :query-string "id=3"
 :server-name "localhost"
 :server-port 4242
 :request-uri "/sns/member?id=3"
 :server-protocol :HTTP/1.1
 :http-user-agent "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-US) ..."
 :http-remote-addr "127.0.0.1"
 :http-remote-port 26077
 :http-referer nil
 :http-host "localhost:4242"
 :http-cookies nil
 :http-server :hunchentoot
 :%request #<request {11A02249}>)

The Request is a list containing at least the following keys and corresponding values.

The Response

Example:

(200
 (:content-type "text/html")
 ("<b>Hello, Lispers!</b>"))

Applications must return a response as a list containing three values.

Handler

Clack Applications run via Clack Handlers, which are in turn responsible for implementing the HTTP protocol and abstracting the server.

Now Clack Applications works on Hunchentoot and Apache, by using following handler.

If you hope them to run on other server (such as AllegroServe or teepeedee2), you can write a handler for it easily.

Middleware

Middleware is one of the Clack Component. It takes another Application and runs it.

Bundle Middleware

How to write Middleware?

All you have to do is to inherit from <middleware> and then implement the callback call method (or make-app method that would return a function) to do the actual work. You can use call-next to call the original (wrapped) application.

(defpackage clack.middleware.example
  (:use :cl :clack)
  (:export :<simple-middleware>))
(in-package :clack.middleware.example)

(defclass <simple-middleware> (<middleware>) ())
(defmethod call ((this <simple-middleware>) req)
  `(200 (:content-type "text/html")
    ,(cons "Hello, Clack Middleware!<br />"
           (nth 2 (call-next this req)))))

(defpackage simple-app
  (:use :cl
        :clack
        :clack.builder
        :clack.middleware.example))
(in-package :simple-app)

(defvar app
  #'(lambda (req)
      '(200 (:content-type "text/plain") ("Hello, Clack!"))))

(clackup (builder <simple-middleware> app))

And you should get following response in time.

Hello, Clack Middleware!
Hello, Clack!

Dependency

Author

Copyright

Copyright (c) 2011 Eitarow Fukamachi

Contributors

License

Licensed under the LLGPL License.