---
title: Getting Started with Liberator
teaser: Get started with Liberator, a Clojure framework for webapps.
tags: web,clojure,liberator
author: Keith Smiley
published_on: 2014-11-18
---

In [Tips for Clojure Beginners][clojure-beginners], Ben laid out some great
resources for starting out with [the language][clojure]. Now, I want to focus on
writing webapps in Clojure using [Liberator][liberator]. We started using
Liberator as the backend for a JSON API and have had a good experience with it
so far. So, I wanted to share a little bit about how to get started.

[clojure-beginners]: https://thoughtbot.com/blog/tips-for-clojure-beginners
[clojure]: http://clojure.org
[liberator]: https://clojure-liberator.github.io/liberator

You have a few options for web frameworks with Clojure. We also considered
[Luminus][luminus], which looks like a great framework, but ultimately decided
on Liberator. It seemed to align better with the single <abbr title="JavaScript
Object Notation">JSON</abbr> API we are creating. Luminus seemed more in tune
with creating full fledged app with a front end. Liberator's
[documentation][documentation] also provides a good [getting started][getting
started] overview which should give you a basic feel for how a Liberator app is
setup.

[luminus]: http://www.luminusweb.net/
[getting started]: https://clojure-liberator.github.io/liberator/tutorial/getting-started.html

Liberator provides functions for creating [resources][resources]. These
resources, similar to resources in other web frameworks, can accept HTTP methods
defined in a vector of `allowed-methods`. Here is a simplified definition for a
resource that accepts a `GET` request:

[resources]: https://clojure-liberator.github.io/liberator/doc/resource-definition.html

```clojure
(defresource bot [id]
  :available-media-types ["application/json"]
  :allowed-methods [:get]
  :handle-ok (fn [_] (get-bot-by-id id)))

(defroutes post-routes
  (ANY "/bot/:id" [id]
       (bot id)))
```

Let's decipher what is happening here. Our newly created resource is now called
from our defined routes. Currently we only have a single route.  Liberator sits
on top of [compojure][compojure] which defines the `ANY` and `GET` functions for
our routes. Instead of specifying the `GET` in our routes we pass any requests
to our resource. This way Liberator will check against our `allowed-methods` and
return the appropriate 405 Method Not Allowed HTTP error code in the case that
it doesn't contain the request type. This entry point to Liberator also provides
a good way for us to separate resources at the same endpoint if needed.

[compojure]: https://github.com/weavejester/compojure

```clojure
(defresource bots []
  :available-media-types ["application/json"]
  :allowed-methods [:get]
  :handle-ok (fn [_] (get-all-bots)))

(defresource post-bots [params]
  :available-media-types ["application/json"]
  :allowed-methods [:post]
  :post! (fn [_] (create-bot params)))

(defroutes post-routes
  (POST "/bots" {params :params}
       (post-bots params))
  (ANY "/bots" []
       (bots)))
```

In this example the `POST` request to `/bots` gets handled first by the
`post-bots` resource while all other requests to the same endpoint get funnelled
through the `bots` resource. This will then throw the appropriate error code for
`PUT` and other unhandled methods.

So far we've seen `post!` and `handle-ok` which are both entry points where we
can override Liberator functionality in our resources. One of the most useful
resources while getting started with Liberator is its massive [decision
graph][graph]. This graph lays out the entire state machine describing the flow
of requests through Liberator. The most useful part of this is that each node in
the graph is a possible entry point for your `resource`s.

You can also see this [decision list][decision list] with the defaults and a
little bit more explanation.

There is also a list of [handlers][handlers], such as `handle-ok` where you can
execute functions after a certain HTTP code has been decided upon by Liberator.
These can be very useful for deciding what to do after a request where you want
to return the representation of the created or updated entity.

[graph]: https://clojure-liberator.github.io/liberator/assets/img/decision-graph.svg
[decision list]: https://clojure-liberator.github.io/liberator/doc/decisions.html
[handlers]: https://clojure-liberator.github.io/liberator/doc/handlers.html

You can create Liberator endpoints that are extremely flexible using these
resources and overriding applicable entry points. Expect to see more posts about
Liberator as we spend more time building out this API.  In the meantime the
[Liberator documentation][documentation] has a ton of very useful information as
you get started.

[documentation]: https://clojure-liberator.github.io/liberator/
