A lot of our internal code base at Exoscale is
written in the Clojure programming language. While its
expressiveness and functional nature makes the language attractive, its lack of
full-application development tutorials makes it a little more difficult to
approach than other languages.

Here is such a tutorial, exploring how to build a simple web application with
the stack we at Exoscale have grown to love.

Enter exopaste: a pastebin application in Clojure

As an example, we’ll write a simple pastebin clone, exposing a service on the
HTTP port, and storing the pastes in an in-memory database.

The principle of pastebin services, in a nutshell, is to allow you to paste
snippets of text, into a web form and retrieve the content later on, via an
invariant URL. This allows to quickly share text and code snippets across the
internet.

Choosing the right Clojure libraries

We’ll use the same stack we tend to use at Exoscale, leveraging the following
libraries:

Aleph for the webserver itself. Aleph is a great webserver
with very good performance characteristics, and we tend to converge towards it
for new projects. It also comes with a convenient HTTP client that can
leverage the same thread pool (if needed), which makes it a very attractive
option. We won’t need all of its power for our simple pastebin service, but
it’s good to know that that power is available should the need arise.

Bidi for the routing library. There are other
good options here, such as
Compojure, but we chose to go with
Bidi, because it also works in ClojureScript out
of the box, and offers a convenient bi-directional (hence the name) approach
to routes, allowing us to know what the route of a particular handler is.

Component to fit everything
together. Component is similar to “dependency injection frameworks” of the
Java world, allowing us to write modular and decoupled applications. We will
leverage its power through this articles to make our paste service able to
“grow” into more and more robust back-ends.

Hiccup for HTML “templating”. Hiccup
allows programmers to define HTML code as a normal Clojure data structure, and
takes care of the rendering into HTML for you. The advantage of this approach
is that your view code is pure Clojure structures that you can use your usual
tools and functions to create.

Writing the exopaste application

The full code for this example application is freely available online on
github, and it is encouraged
to refer to the full source code there while reading this post. The snippets
provided here generally do not show the whole file but rather highlight specific
parts.

Get started with Leiningen

Leiningen is the most popular way to manage Clojure
projects, and deals with the project’s release and dependency management for us.
It serves as the entry point to your Clojure project as a developer. A few of
the (many) useful commands:

lein run will run your project’s “main” function after making sure all the
dependencies are up to date.

lein test will run your project’s tests

lein uberjar probably the least intuitive here, this command will bundle up
your project and all its dependencies in a single executable jar, allowing
your to run it with java -jar directly.

The command that interests us most right now however is the lein new command,
which will write out the skeleton of a Clojure project for us to start from:

lein new app exopaste

We won’t need the “core” module the template generates for us, so we can get rid
of it now:

rm src/exopaste/core.clj
rm test/exopaste/core_test.clj

Let’s replace the default project file with our own, including some of the
dependencies we have chosen:

Building a Clojure application with components

We use components a lot at Exoscale, since they allow flexible run time
composition of applications.

For our simple pastebin clone, we’ll need just a couple of components:

A webserver component that will handle the aleph startup and bidi routes.

An in-memory “store” for our pasted data to live in. The reason we’ll make it
a component here (as opposed to a simple module with functions) is to allow
further articles to build upon this foundation and make our application save
its data in a real database.

What are components exactly?

Components are implemented as clojure
records, which you can think of as a
Map where the fields are declared, and on which functions can be bound.

Furthermore, Clojure allows the definition of
protocols, which declare a group of
functions that records must implement.

Our components are records that implement the “Lifecycle” protocol, that defines
two simple functions: start and stop.

;; This is what the Lifecycle component looks like. You don't need to write this
;; as it's already part of the component library.
(defprotocol Lifecycle
(start [x]) ;; What to do when the component is started.
(stop [x])) ;; What to do when the component is stopped.

Those functions define what should happen when the component starts (typically,
setup some external state such as a database connection), and what should be
done when it is stopped (closing the connection).

The system map

In order for our components to be started, we need to build a system map using
the aptly named (component/system-map) function. What we do here is tell the
component system which components to actually use, a little bit like what
inversion of control frameworks of the java world would do (conceptually similar
to the Spring framework, for example).

This allows us to build very simple components first (such as our in-memory
store), that we will later be able to easily swap for another implementation,
for instance using a real database as a back-end instead of simply storing data
in-memory.

While the (system-map) call describes the list of components we have, the next
call, (system-using) describes the relationship between them. In our case, for
now the only relationship we declare is that our server component should know
about and be allowed to access our storage component.

Behind the scenes, the components library will add a :store entry to the
server component (a component is conceptually a map).

A simple Clojure webserver component

In order to serve our pastes, we’ll need a server component that is in charge of
serving HTTP. We need very few things here: an URL to which to paste a new paste
to, a URL with which to read pastes (by identifier), and a top-level form with which
to present the form.

As you notice, we pass it the result of the (handler) function, that builds
the bidi handler. The handler is what maps the
URLs your users will input to functions (that produce the content to display in
the client).

The handler function also receives the store, as an entry in the server
component map. This allows us to “forward” a reference to the store to our
paste handler:

This will return the result of the index-handler and paste-handler functions
to the HTTP client when launched via the system map, and we can immediately see
how the paste’s uuid parameter will be passed to our handling function.

Notice that the handler makes use of the (partial) function around the handler
functions. The reason for this is that our handlers would like to have two
parameters - the request, and the store. However the ring specification says
that handlers will only get a single parameter - the request. The partial
function binds the store to our
handler, and returns another function that now takes a single argument.

The store component

We need a place to store the data we send to our exopaste server. For now, we’ll
build a very simple storage component that leverages a Clojure
“atom” - a Clojure concurrency primitive
wrapping arbitrary state - as an in-memory data-store.

During our store component’s initialization, we set its “data” field to a fresh
new (atom). If we had a database connection (for example), we would also need
to close it at program shutdown in the (stop) function.

Hiccup: Clojure HTML templating and rendering

Our pastebin app still needs to render actual HTML to the client’s web browser.
For this, we’ll create a new module, that will leverage the
Hiccup library to render HTML.

Hiccup is a neat Clojure library that makes it convenient to create HTML with
Clojure syntax, and since all of the data you write is just that - data - you
can use all the power of Clojure to compose your view.

For our simple pastebin application, we will need just two views: one to render
a paste, and one to display the paste form to our users.