Building Web Application with Clojure + ClojureScript

Building Web Application with Clojure + ClojureScript

Brief overview of Clojure/ClojureScript web stack.

(Download PDF version of the presentation to open the links in it)


Ivan Kryvoruchko

July 15, 2013


  1. Building web application with Clojure + ClojureScript

  2. whoami Ivan Kryvoruchko Programming background: ActionScript 3 (games) Python (Django,

    text parsing) Java (EE) Contacts: gsnewmark @gsnewmark
  3. Example Application Source code: Bookmark management application: Store

    bookmarks, tag them, filter by tag, add notes Simple search Recommendations Clojure (server) + ClojureScript (client) Runs on Heroku Neo4j as a database Search is powered by ElasticSearch
  4. Clojure Overview LISP: REPL, homoiconicity, macros, parenthesis... Runs on JVM

    (good Java interop) Leiningen for project automation and configuration (based on Maven) Dynamic typing (although type hints could be used) Number of standard immutable data structures (list (), vector [], map {}, set #{}) Immutability is preferred over mutability (for later number of tools exist: atoms, refs, transients, etc.) Nice destructuring capabilities
  5. Clojure Primer Everything is an expression First-class functions, which are

    the basic building blocks of every program Related functions are stored in namespaces (roughly equivalent to Java's classes) Symbols (a, map, reduce) evaluate to some value from current scope Lists ((map identity [1 2 3])) are used to perform actions: their first element is operator and rest are arguments (so called prefix notation) All other expressions ("string", 42, :keyword) evaluate to themselves ; is used for comments
  6. Clojure Code Example (ns overly.complex.hello) (def hello-messages {:eng "Hello, World!"

    :ukr "Привіт, Світе!"}) (def hello-fn (fn [] (println "Hello, World!"))) (defn hello [messages lang] (println (get messages lang))) (def default-hello (partial hello hello-messages))
  7. Clojure Web Stack Community favors using small composable libraries over

    large frameworks Some frameworks still exist: Luminus CHP Pedestal
  8. Basic HTTP interaction Ring - analogue of Rack (Ruby) and

    WSGI (Python) Requests and responses are represented as Clojure maps {:status 200 :headers {"Content-Type" "application/edn;charset=utf-8"} :body "[41 42 43]"} Responses are generated using the handlers - plain Clojure functions that take Ring request map as input and return Ring response map as output Additionally, requests could traverse a chain of middleware - something like interceptors, higher-order functions, that somehow modify request, response, or both Low-level HTTP interaction is delegated to the so called adapter (for instance, Jetty server or HTTP Kit)
  9. Routes Compojure - DSL for routes declaration Provides macro that

    connects handlers with specific routes - as a result a new Ring-complaint handler is obtained Also allows combining and nesting obtained route maps (defroutes internal-api (GET "/resources" req (retrieve-resources)) (POST "/resources/:id" [id :as {{e-mail :e-mail} :session}] (add-resource! e-mail id)))
  10. Templates Enlive - selector-based templating (and parsing) system A bit

    like jQuery for the server Takes plain HTML as input, extracts some parts of it using selectors and chages them using transformers Template functions are simply Ring handlers Good for teams with a designer (deftemplate index "templates/index.html" [user] [:span#user] (content user)) Alternatives: Hiccup, Clostache, Clabango, Laser
  11. Security Friend -authentication and authorization library Role-based (roles are simply

    Clojure keywords) Supports different workflows (ranging from simple form-based to OAuth) Middleware + number of higher order functions to restrict access to specific handlers (defn handler ;; ...Ring handler... ) (def secured-handler (wrap-authorize handler #{:user-role})) (def friend-enabled-secured-handler (authenticate secure-handler {:workflows [(comment «some workflows»)] :login-uri «/»}))
  12. Miscellaneous Helpers ClojureWerkz - collections of useful Clojure libraries, mainly,

    but not only, clients for different data storages Thoroughly documented and tested Some of the libraries: Neocons - client for Neo4j server REST API Elastisch - client for ElasticSearch REST API Quartzite - scheduling library (uses Quartz Scheduler)
  13. ClojureScript Overview Subset of Clojure But compiles to JavaScript (compiler

    is written in Clojure) Uses Google Closure compiler to further minify and optimize obtained code cljsbuild Leiningen plugin automates compilation/ recompilation and other common tasks
  14. Sharing Code cljsbuild crossovers - enables compilation of Clojure source

    files into JavaScript if Clojure-specific features are not used (for instance, concurrency, Java interop) cljx - uses it’s own source files with specific annotations, which define when given forms should be used (during Clojure compilation, ClojureScript compilation, or both) (defn current-date-time [] (let [time #+clj (java.util.Date.) #+cljs (Date.)] time))
  15. DOM Manipulation/ Templating/Events Enfocus - inspired by Enlive (has similar

    selectors/ transformers API), so quite natural to use in pair with it Supports events (at js/document [«.ok-button»] (listen :click (fn [e] (.log js/console «clicked»)))) Alternative: Dommy
  16. ClojureScript Helpers shoreleave - set of libraries that simplify everyday

    front- end tasks shoreleave-pubsub - implementation of Publish/ Subscriber model (useful for separating presentation and behavior) shoreleave-remote - simplified interface to creation of XMLHttpRequests as well as HTTP-RPC implementation
  17. Hosting Clojure applications could be deployed on nearly every hosting

    that supports Java (specifically, JARs/WARs) Heroku - nice «native» Clojure support Application could be automatically built and deployed from it’s source code using Git Phil Hagelberg (main developer of Leiningen) is in Heroku team
  18. Useful Resources Community-driven Clojure Documentation Clojure Libraries repository Ring SPEC

    Simple Made Easy Hammock-driven Development