Introducing playnice


Today I am happy to announce playnice, a Clojure library of tools to help build HTTP standards compliant servers.

Existing libraries for developing web services focus mainly on ease. They try to make it easy to get started. They implement a naive, yet functional, version of the HTTP spec. It is basically the simplified understanding of HTTP that we all think in. A client makes requests to URLs, and the server responds with either an error or content.

But the HTTP spec is more complete than merely matching URLs and methods. There are many error classes defined in the spec and much functionality dealing with the meta-level of the capabilities of the server itself. In addition, there are many de facto standards and workarounds that should be baked into the server.


  1. Make it easier to serve HTTP standard responses without confounding HTTP logic with business logic.
  2. Make it easier for limited or non-standard clients to access resources.
  3. As much as possible separate orthogonal functionality into composable chunks.

playnice was named because it plays nice with others. The Web is a wide world, and there are lots of clients out there. You should follow the spec as closely as possible, but accept that not all clients are so strict. Also, there is a variety of input and output formats. You should play nice with them, if you can. playnice is a library to help Clojure programs play nice with the rest of the web.

playnice Opinions

  • URL first, method second.

    HTTP is about resources, which are identified by URLs. Different resources accept different methods. If a GET at a URL responds 200, but a POST is not supported, a 405 should be returned, not a 404.

  • Routes are values that do not exist in the global namespace.

    Routes are immutable and first-class.

  • The order of defining routes should not matter.

    Reordering my routes should not cha nge the behavior of my server. Routes are declarative.

  • Servers should support the OPTIONS method and correct handling of unsupported methods.

    OPTIONS returns the methods that are defined for a given URL.

  • Servers should support the Accept and Content-type headers of requests.

    The handler is the wrong place to parse the Content-type header to figure out what kind of data you have been given. playnice currently supports HTML, JSON, TXT, and Clojure literals. I hope to have XML soon.

  • *Servers should support *de facto* standards and common workarounds.*

    "Redirecting after form post" is a de facto standard for browsers. IE does not support DELETE method in AJAX, so the workaround is to do a POST with a special query parameter set to DELETE.


playnice is still in early development, but it already contains the following components:

  • Route + method dispatch (replacing Compojure).
  • Middleware for abstracting away input and output formats.
  • Middleware for handling "redirect after form post".
  • Middleware for working around browser limitations.

Please check out playnice if you need an HTTP compliant web server.