Skip to content

Instantly share code, notes, and snippets.

@karnie6
Last active August 29, 2015 14:09
Show Gist options
  • Save karnie6/912104e79a1354febf8b to your computer and use it in GitHub Desktop.
Save karnie6/912104e79a1354febf8b to your computer and use it in GitHub Desktop.
invalid article card 1
{
"card_type": "article",
"web_url": "http://robots.thoughtbot.com/getting-started-with-liberator",
"article": {
"title": "Getting Started with Liberator",
"html_content": "\n<p>In <a href=\"http://robots.thoughtbot.com/tips-for-clojure-beginners\">Tips for Clojure Beginners</a>, Ben laid out some\ngreat resources for starting out with <a href=\"http://clojure.org\">the language</a>. Now, I\nwant to focus on writing webapps in Clojure using\n<a href=\"https://clojure-liberator.github.io/liberator\">Liberator</a>. We started using Liberator as the backend for a\nJSON API and have had a good experience with it so far. So, I wanted to\nshare a little bit about how to get started.</p>\n\n<p>You have a few options for web frameworks with Clojure. We also\nconsidered <a href=\"http://www.luminusweb.net/\">Luminus</a>, which looks like a great framework, but\nultimately decided on Liberator. It seemed to align better with the\nsingle JSON API we are creating. Luminus seemed more in tune with\ncreating full fledged app with a front end. Liberator’s\n<a href=\"https://clojure-liberator.github.io/liberator/\">documentation</a> also provides a good <a href=\"https://clojure-liberator.github.io/liberator/tutorial/getting-started.html\">getting\nstarted</a> overview which should give you a basic feel\nfor how a Liberator app is setup.</p>\n\n<p>Liberator provides functions for creating <a href=\"https://clojure-liberator.github.io/liberator/doc/resource-definition.html\">resources</a>. These\nresources, similar to resources in other web frameworks, can accept HTTP\nmethods defined in a vector of <code>allowed-methods</code>. Here is a simplified\ndefinition for a resource that accepts a <code>GET</code> request:</p>\n\n<pre><code class=\"clojure\">(defresource bot [id]\n :available-media-types [\"application/json\"]\n :allowed-methods [:get]\n :handle-ok (fn [_] (get-bot-by-id id)))\n\n(defroutes post-routes\n (ANY \"/bot/:id\" [id]\n (bot id)))\n</code></pre>\n\n<p>Let’s decipher what is happening here. Our newly created resource is now\ncalled from our defined routes. Currently we only have a single route.\nLiberator sits on top of <a href=\"https://github.com/weavejester/compojure\">compojure</a> which defines the <code>ANY</code>\nand <code>GET</code> functions for our routes. Instead of specifying the <code>GET</code> in\nour routes we pass any requests to our resource. This way Liberator will\ncheck against our <code>allowed-methods</code> and return the appropriate 405\nMethod Not Allowed HTTP error code in the case that it doesn’t contain\nthe request type. This entry point to Liberator also provides a good way\nfor us to separate resources at the same endpoint if needed.</p>\n\n<pre><code class=\"clojure\">(defresource bots []\n :available-media-types [\"application/json\"]\n :allowed-methods [:get]\n :handle-ok (fn [_] (get-all-bots)))\n\n(defresource post-bots [params]\n :available-media-types [\"application/json\"]\n :allowed-methods [:post]\n :post! (fn [_] (create-bot params)))\n\n(defroutes post-routes\n (POST \"/bots\" {params :params}\n (post-bots params))\n (ANY \"/bots\" []\n (bots)))\n</code></pre>\n\n<p>In this example the <code>POST</code> request to <code>/bots</code> gets handled first by the\n<code>post-bots</code> resource while all other requests to the same endpoint get\nfunnelled through the <code>bots</code> resource. This will then throw the\nappropriate error code for <code>PUT</code> and other unhandled methods.</p>\n\n<p>So far we’ve seen <code>post!</code> and <code>handle-ok</code> which are both entry points\nwhere we can override Liberator functionality in our resources. One of\nthe most useful resources while getting started with Liberator is its\nmassive <a href=\"https://clojure-liberator.github.io/liberator/assets/img/decision-graph.svg\">decision graph</a>. This graph lays out the entire state\nmachine describing the flow of requests through Liberator. The most\nuseful part of this is that each node in the graph is a possible entry\npoint for your <code>resource</code>s.</p>\n\n<p>You can also see this <a href=\"https://clojure-liberator.github.io/liberator/doc/decisions.html\">decision list</a>\nwith the defaults and a little bit more explanation.</p>\n\n<p>There is also a list of <a href=\"https://clojure-liberator.github.io/liberator/doc/handlers.html\">handlers</a>, such as\n<code>handle-ok</code> where you can execute functions after a certain HTTP code\nhas been decided upon by Liberator. These can be very useful for\ndeciding what to do after a request where you want to return the\nrepresentation of the created or updated entity.</p>\n\n<p>You can create Liberator endpoints that are extremely flexible using\nthese resources and overriding applicable entry points. Expect to see\nmore posts about Liberator as we spend more time building out this API.\nIn the meantime the <a href=\"https://clojure-liberator.github.io/liberator/\">Liberator documentation</a> has a ton\nof very useful information as you get started.</p>\n\n",
"abstract": "Get started with Liberator, a Clojure framework for webapps.",
"publication_date": "2014-11-18T00:00:00+00:00"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment