free-from

Free-form version 0.2.0 released

We are very happy to announce version 0.2.0 of our form building library Free-form. This version includes:

The Bootstrap 3 support means that you can have whole fields defined as succinctly as:

[:free-form/field {:type        :email
                   :key         :email
                   :label       "Email"}]]

Enjoy!

 

prerenderer

Prerenderer 0.2.0 released

We are proud to announce the release of version 0.2.0 of our ClojureScript library Prerenderer, a library to do server side pre-rendering of single page applications. In this release, we include:

The two first items in the changelog came hand in hand and they are the biggest changes to keep in mind if you are upgrading. We are very happy that we no longer need a fork of re-frame and we would like to extend our gratitude to Mike Thompson for working with us on having the appropriate API to make this happen.

The change in API means that your Prerenderer module now would look something like this:

(ns projectx.node
  (:require [prerenderer.core :as prerenderer]))

(defn render-and-send [page-path send-to-browser]
  (send-to-browser (render page-path)))

(set! *main-cli-fn* (prerenderer/create render-and-send "ProjectX"))

instead of:

(ns projectx.node
  (:require [cljs.nodejs :as nodejs]
            [prerenderer.core :as prerenderer]))

(defn render [req res]
  (let [page-path (.-path (.parse url (.-url (.-query req))))]
    (.send res (render page-path))))

(set! *main-cli-fn* (prerenderer/create render "ProjectX"))

Enjoy!

bruce-at-clojure-exchange

Review of Clojure Exchange 2015 London

I recently attended Clojure Exchange 2015 London, the conference organized by Skills Matter for Clojurians. Like many other attendees I was impressed by the quality of the talks and as a presenter, I was particularly pleased that only a few hours later my presentation, What is a Macro?, was already published, in video form, for everybody to see.

Some presentations I found particularly interesting were:

Yada for RESTfull APIs

Malcolm Sparks presenting Yada in RESTfull web service in Clojure, two different approaches. Yada is a library to create RESTfull APIs that focus on succinctness and on doing as much work for you as possible so you only focus on your business model. Yada is also async-ready and you can stream results. We will consider using it instead of Compojure-API in the future, although we still have to explore how to integrate it with other Clojure components. One limitation it has is that it can only work with Aleph, because the other web services don’t provide back pressure.

Clojurescript: Architecting for Scale

Kris Jenkins presenting his pattern in ClojureScript: Architecting for Scale. Kris shows us how he writes ClojureScript single page applications so he doesn’t end up with a spaghetti of code. The pattern is implemented as a library that he just released for the conference, called Petrol. We are happy to see how close the pattern is to our favorite one, as provided by Re-frame, that we use in Ninja Tools and we plan on using in future projects. Clearly the reactive pattern seems the way to go to write client applications beyond Hello World.

Duct, Covered with James Reeves

James Reeves presenting his aggressively simple framework for writing web applications with Clojure in Duct, Covered. You might know James as weavejester, the author of compojure, environ and so many other super popular libraries. Duct is his take on the web framework arena. It can be said to be similar to Luminus, but its emphasis is in the set up of a componentized system. Something that is easier to ignore at first and comes back to bite you later on. I had a private conversation with James after his presentation and I’m really excited about the future of Duct.

Compared to other conferences I’ve been to, it surprised me how many authors of popular open source libraries and tools we had on stage and that made me wonder how many were in the audience that I didn’t know about. I wished I had better visibility into this as I think cooperation makes for a better ecosystem.

One problem I see in the Clojure world right now is fragmentation; we are all inventing our own ways of doing things instead of compromising a bit, cooperating, and making some ways of doing things faster, better, more tested, friendlier, better documented, and so on.

Saying that, the experience was brilliant and I already bought my ticket for next year’s Clojure Exchange at the bargain price of £95.00+VAT. Do you have yours?

 

Tour of the Source Code of Ninja Tools

Notes and links

  • What is a Single Page Application? A previous screencast describing what a single page application is and why they are the future.
  • Ninja Tools: discover tools that work with your current tools, learn about better ways to use them, get alerts, etc.
  • Clojure: the programming language we are using.
  • ClojureScript: the programming language that is saving is from JavaScript.
  • Luminus: a template to get started with web applications without having to reinvent the wheel.
  • Yesql: a SQL interfacing library for Clojure.
  • Migratus: a migration library for Clojure, to modify the database schema.
  • Conman: a connection manager for Yesql.
  • React: Facebook’s library to develop JavaScript UIs.
  • Reagent: a wrapper for React to use it in ClojureScript.
  • Re-frame: a library to develop web UIs with the reactive pattern.
  • Validateur: validation library for Clojure and ClojureScript.
closed

Don’t forget to clear your client side state when logging a user out

When a user logs out from our web site, we are used to clearing the session and that’s it. When you are developing a single page application, you are likely to keep a lot of state on the client side, and that should be cleared too.

For Ninja Tools, that meant going from the traditional re-frame initialize-db:

(re-frame/register-handler
  :initialize-db
  (fn [_ _]
    (re-frame/dispatch [:get-current-user])
    {:current-route        nil
     :alerts               (sorted-map)
     :current-user         nil
     :log-in-form          {}
     :registration-form    {}
     :reset-password-form  {}
     :change-password-form {}
     :tools                nil
     :used-tools           nil}))

to having the initial-db in a re-usable value:

(def initial-db {:current-route        nil
                 :alerts               (sorted-map)
                 :current-user         nil
                 :log-in-form          {}
                 :registration-form    {}
                 :reset-password-form  {}
                 :change-password-form {}
                 :tools                nil
                 :used-tools           nil})

(re-frame/register-handler
  :initialize-db
  (fn [_ _]
    (re-frame/dispatch [:get-current-user])
    initial-db))

and our logged-out handler to use it instead of modifying the current estate, which meant going from:

(re-frame/register-handler
  :logged-out
  (fn [db [_]]
    (routing/redirect-to :home)
    (-> db
        (assoc :current-user nil)
        (alerts/add-alert :success "You are now logged out."))))

to:

(re-frame/register-handler
  :logged-out
  (fn [db [_]]
    (routing/redirect-to :home)
    (-> db/initial-db
        (alerts/add-alert :success "You are now logged out."))))

Since we care so much about security, for us, it’s important to go back to initial-db, and if there’s some state that should survive, we’ll pass it on manually. That is, we’ll be doing whitelisting vs blacklisting.

Something that we haven’t decided is whether we clear the state on log-out, when the user just clicked the log out link, or logged-out, when when the server has cleared the session.

The advantage of the former is that we clear all the state as soon as possible, the advantage of the later is that should the log out procedure fail for some reason, the app still has the state and it should still be usable, which might be required for re-trying logging out.

Recapping that, clearing state immediately behaves better when everything goes well, clearing state later behaves better when something goes wrong during the log out process. We can’t comment one being safer that the other, as clearing the session earlier and failing to log out might leave the user under the impression they successfully logged out when it’s not the case.

Picture by Ken Hawkins.

prerenderer

Isomorphic JavaScript (with ClojureScript) for pre-rendering single-page-applications, part 3

I was not expecting there to be a part 3 to this series and this third part is also going to be quite different to the first two. In parts 1 and 2 I walked you through an exploration of server side pre-rendering with Nashorn. My naive example worked fine with Nashorn but it didn’t survive encountering the real world.

Nashorn is not a headless browser, it’s a plain JavaScript engine. It doesn’t implement document or window for example, which were easy to workaround, but it also doesn’t implement setTimeout, setInterval or XMLHttpRequest which are much harder to workaround.

When I started to look for alternatives I focused on NodeJS because I knew if implemented those things I was missing and V8‘s speed is attractive. Also, the fact the ClojureScript has it as a compilation target made me feel it was well supported, a first class citizen.

At this point someone might interject and exclaim: What about nodyn.io? nodyn.io is an attempt to bring all the NodeJS goodness to Nashorn and I think it’s a great idea. Sadly, on GitHub we can find this notice:

This project is no longer being actively maintained. If you have interest in taking over the project, please file an issue.

I’m not sure if the project got far before being abandoned either.

Implementing the missing bits of Nashorn in Clojure was tempting. It looks like fun and it also looks like something that might be popular amongst Java users and thus good for the Clojure echo system. I exercised some restrain and moved on.

In the process of experimenting with NodeJS my code quickly took the form of a library and without further ado, let me introduce you to Prerenderer. The ultimate solution for all your server side pre-rendering needs. I’m not going to show you how to use it here because its page go into a lot of detail already.

My big concern about prerendering is performance and stability. As I showed in part 2, a naive implementation can behave horribly while in production, sometimes taking up to 17 seconds to serve a page. Prerenderer was not developed with a sample project, like I did with Nashorn, but with a project we are working on called Ninja Tools that uses re-frame and AJAX. Before any modifications to it, this was its performance:

Ninja Tools performance with no server side rendering

After enabling Prerenderer, this is how it looks like:

Ninja Tools with Prerenderer

The average response time went up from 51ms to 362ms. This would generally be a very bad thing. The reason for this is explained in Prerenderer’s documentation:

[…] SPAs are never done. Imagine a SPA that has a timer and every second sends a request to the server, and the server replies with the current time, which then the application displays. When is it done rendering? Never. But Prerenderer needs to, at some point, decide that the page is done enough and ship it to the browser. […]

[…] Prerenderer will watch for events and once nothing happened for a period of time (300ms by default) it’ll consider the application done and if a certain amount of time went by (3s by default) even if the application is still active, it’ll stop and send it to the browser.

That’s where the jump in 300ms is coming from and it’s constant. It’s not linear and definitely not exponential. It’s a constant number that can be tuned and tweaked. There are also some potential optimizations to reduce it or remove all together.

The important thing is that all other values remained more or less the same and that the performance characteristics where quite stable. For me, this feels good enough to move on and start producing SPAs and with a bigger codebase we’ll be able to improve this library and make it better.

Picture by Ian Farrel