One Ring to Bind Them

3,805 views

Published on

1 Comment
4 Likes
Statistics
Notes
No Downloads
Views
Total views
3,805
On SlideShare
0
From Embeds
0
Number of Embeds
14
Actions
Shares
0
Downloads
58
Comments
1
Likes
4
Embeds 0
No embeds

No notes for slide
  • thanks stu

  • so, ring
  • ring is a tool for writing http services in clojure
  • put another way
    ring helps you write web apps in clojure




  • not go through mechanics, why
    it’s best to udnerstand not as a list of features but as a line of reasoning
  • how that power leads to better apps
  • how that power leads to better apps
  • how that power leads to better apps
  • so let’s start at the beginning
    this is an http request to your clojure web service
    what you would like to do is take this http request,
  • apply your clojure application logic
  • and generate an http response, like this one
    seems easy enough
  • it’s just http to clojure and back
    but if you try working with raw http in your app, or with an http-specific api like, say, servlets,
  • you are going to be sad
    the reason is that the http protocol is not the essence of your particular app
    that essence is more like
  • this
  • the fact that http looks like this on the socket coming in
  • or like this going out
    are not details you want to concern your application code with
  • abstraction
  • so what then is the abstraction?
  • well, we said our app was essentially this
    which looks suspiciously like a function
  • there, that’s better
    now the request is really more than /welcome
  • we really need to include various named fields, like the protocol, request method, uri, and host. key-value pairs: sounds like a map to me
  • so ring represents http requests as vanilla clojure maps
  • likewise http responses are logically a set of key-value pairs
  • so we again use clojure maps to represent http responses in ring

  • so the upshot of is that our web application looks like this
    the http application is a function
    that function takes a map as an argument, representing the http request
    that function then returns a map, representing the http response
    this is simple to the point of being obvious, but it’s really important
  • the reason is that we’ve lifted http into the space of clojure’s maps and functions
    these are universal interfaces that clojure the language, clojure programs, and clojure libraries all understand

  • the reason is that we’ve lifted http into the space of clojure’s maps and functions
    these are universal interfaces that clojure the language, clojure programs, and clojure libraries all understand

  • the reason is that we’ve lifted http into the space of clojure’s maps and functions
    these are universal interfaces that clojure the language, clojure programs, and clojure libraries all understand

  • defining middleware
  • defining middleware
  • defining middleware

  • composing middleware
  • likewise you don’t need any ring-specific gear to test your applications - they are just functions on data. Indeed the look exactly any other Clojure function, so why not unit test them the same way you unit test all of your other Clojure code.

  • all of that clojure’s general functional programming awesomeness transitively applies to web app development, for free
    so abstraction, and in particular choosing the right abstraction
    which is nice
  • but i promised you this
    right
    we’ll get that last bit by taking our power and applying
  • leverage

  • leverage

  • it says what those maps needs to look like and what that function needs to do

  • the spec is short and mostly obvious, but its critical because it allows all kinds of libraries to easily participate in your application
  • ring itself is part library
  • ring itself is part library
  • it includes some basic web building blocks out of box
    these are some examples
    but these are really just for convenience of distribution
    anyone can write a ring component that works with that spec
  • batteries inclued, hello world and basic funtionality that you would expect of a web applicaiton library
  • response example
  • session store as example of providing common interface
  • and it can immediately participate in the ring ecosystem
    instead of a bunch of project on github like rails-my-extensions we have a bunch like ring-my-extension, that can then be shared easily among all
  • we’re seeing a lot of great stuff built around Ring
  • a couple areas that i’d like to highlight are frameworks, adapters, and middleware


  • ~ can run and augment orthogonally
  • then in part because it doesn’t need to touch http at all, and part because it leverages other ring-based libraries, compojure itself is really small
    so if you ever have a problem with compojure, or just want to know how it works, you could just read the entire source in a few minutes






  • so what you end up with is you have base app that defines our core routing and business logic
    and then you take some middleware from ring core, pull in some middleware from the ring ecosystem, and tyically also have a few of your own middleware that are specific for this project
    what middleware config looks like in one of my apps

    so
  • so the ring abstraction leads to power, which in turn allows you to write better http apps in clojure
    what i’d like to do now is

  • generalize this slightly
    into some thoughts about library design in clojure
  • the key for ring’s design was taking http, and transforming it into the space of clojure’s pervasive abstractions
  • in a well-specified way that enabled composability
  • in particular composability that extended across orthogonal components that were written independently, but again all leveraging clojure’s core strengths
  • composability across developers and through clojure’s extensive functional programming library
    this is what i call
  • composable abstraction


  • to me, personally, this notion of composable abstraction is the essence of clojure

  • i see all of clojure’s bullet-point features
    i think ring is an instance of this - i hope i’ve convinced you of that - but it’s also a sort of archetype for clojure library design

  • this notion worked well with ring, but where could it be useful elsewhere
  • we actually don’t even need to leave http to see a great example
    you could apply the same trick here



  • because then, again, you immediately benefit from the power of clojure
    everything is functions and data, and clojure is brilliant with those

  • so looking back on our original list for ring
    i’d say that ring is the direct result of a library design approach that can - and i think should - be applied to more problems

  • in other words, if you want steps 2 and 3 here
  • you have to the step one right, abstraction
  • thanks for listening everyone
    i’d love to take some questions
  • thanks again

  • ×