Web Development
46.1 Hunchentoot (Web Server)
REPL-driven web development: redefine a handler, and the next request uses the new code immediately.
(ql:quickload '("hunchentoot" "spinneret" "com.inuoe.jzon"))
(defvar *server* (make-instance 'hunchentoot:easy-acceptor :port 4242))
(hunchentoot:define-easy-handler (home :uri "/") ()
(setf (hunchentoot:content-type*) "text/html")
(spinneret:with-html-string
(:html
(:head (:title "Lisp Web"))
(:body (:h1 "Hello from Common Lisp")
(:p "Served by Hunchentoot")))))
(hunchentoot:define-easy-handler (hello :uri "/hello") (name) ; query/form parameter ?name=...
(setf (hunchentoot:content-type*) "text/plain")
(format nil "Hello, ~a!" (or name "world")))
(hunchentoot:define-easy-handler (api-items :uri "/api/items") ()
(setf (hunchentoot:content-type*) "application/json")
(com.inuoe.jzon:stringify #(1 2 3)))
(hunchentoot:start *server*) ; visit http://localhost:4242/
;; (hunchentoot:stop *server*)46.2 Clack/Lack, Ningle and Caveman
Web application environment and middleware (like Rack/WSGI) Mature, standalone web server High-performance server (libev)
Caveman2, Ningle, Snooze, Radiance Frameworks / routing Spinneret, cl-who, Djula HTML generation / templates
Build web/desktop GUIs from Lisp over WebSockets Dexador, Drakma websocket-driver, hunchensocket cl-jwt, cl-bcrypt/ironclad Auth and crypto
(ql:quickload '("clack" "ningle"))
(defvar *app* (make-instance 'ningle:app))
(setf (ningle:route *app* "/") "Welcome to ningle!")
(setf (ningle:route *app* "/users/:id")
(lambda (params) (format nil "User ~a" (cdr (assoc :id params)))))
(clack:clackup *app* :server :woo :port 5000) ; Woo: a very fast libev-based server;; HTTP client
(ql:quickload "dexador")
(dex:get "https://api.github.com/repos/sbcl/sbcl") ; body, status, headers, uri, stream
(dex:post "https://httpbin.org/post" :content "{\"a\":1}" :headers '(("Content-Type" . "application/json")))