New upstream version 0.3.1

language: clojure
lein: lein2
- oraclejdk7
- openjdk7
script: ./ext/travisci/
email: false
- qiD4Yo5b7i1tz3kUW0ttsqoH0a1ZYVFihzThWtPT@322656
- "%{repository}#%{build_number} (%{branch} - %{commit} : %{author}): %{message}"
- "Change view: %{compare_url}"
- "Build details: %{build_url}"
## 0.3.1
This is a minor bugfix release.
* [TK-297]( : Fix bug where `wrap-routes` didn't work properly with certain kinds of bidi route trees - Michal Růžička <> (159ef0f)
* Update dependencies on clojure, bidi, compojure, schema
## 0.3.0
Added mechanism for wrapping intermediate comidi routes with middleware.
Added support for "true/false" Bidi patterns.
## 0.2.2
Same content as 0.3.0 - please prefer that version
## 0.2.1
Added 'resources' route utility fn.
Routes can now only map to Ring handlers.
## 0.2.0
Make use of schema introduced in Bidi 1.20.0 (SERVER-777).
## 0.1.3
Improved dependency specification.
## 0.1.2
Upgrade compojure to 1.3.3 for Clojure 1.7.0 compatibility.
## 0.1.1
Make repository public, deploy to clojars.
## 0.1.0
Initial release, with the goal of soliticing API feedback.
# How to contribute
* Make sure you have a [GitHub account](
* Fork the repository on GitHub
## Making Changes
* Create a topic branch from where you want to base your work (this is almost
definitely the master branch).
* To quickly create a topic branch based on master; `git branch
fix/master/my_contribution master` then checkout the new branch with `git
checkout fix/master/my_contribution`.
* Please avoid working directly on the
`master` branch.
* Make commits of logical units.
* Check for unnecessary whitespace with `git diff --check` before committing.
* Make sure your commit messages are in the proper format.
Make the example in CONTRIBUTING imperative and concrete
Without this patch applied the example commit message in the CONTRIBUTING
document is not a concrete example. This is a problem because the
contributor is left to imagine what the commit message should look like
based on a description rather than an example. This patch fixes the
problem by making the example concrete and imperative.
The first line is a real life imperative statement with a ticket number
from our issue tracker. The body describes the behavior without the patch,
why this is a problem, and how the patch fixes the problem when applied.
* Make sure you have added the necessary tests for your changes.
* Run _all_ the tests to assure nothing else was accidentally broken.
## Submitting Changes
* Sign the [Contributor License Agreement](
* Push your changes to a topic branch in your fork of the repository.
* Submit a pull request to the repository in the puppetlabs organization.
# Additional Resources
* [Contributor License Agreement](
* [General GitHub documentation](
* [GitHub pull request documentation](
Copyright (C) 2005-2015 Puppet Labs Inc
Puppet Labs can be contacted at:
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
See the License for the specific language governing permissions and
limitations under the License.
# comidi
A committee approach to defining Clojure HTTP routes.
[![Build Status](](
Comidi is a library containing utility functions and [compojure]( syntax-sugar
wrappers around the [bidi]( web routing library.
It aims to provide a way to define your web routes that takes advantage of the
strengths of both bidi and compojure:
* Route definitions are, at the end of the day, simple data structures (like bidi),
so you can compose / introspect them.
* Helper functions / macros for defining routes still provide the nice syntax
of compojure; destructuring the request in a simple binding form, 'rendering'
the response whether you define it as a string/map literal, a function reference,
an inline body form, etc.
## Quick Start
[![Clojars Project](](
(let [my-routes (context "/my-app/"
(GET "/foo/something" request
(POST ["/bar/" :bar] [bar]
(str "bar:" bar))
(PUT ["/baz/" [#".*" :rest]] request
(call-baz-fn request))
(ANY ["/bam/" [#"(bip|bap)" :rest]] request
{:orig-req request
:rest (-> request :route-params :rest)))
app (-> (routes->handler my-routes)
(add-ring-handler app))
Notable differences from compojure above:
* use vectors to separate segments of a route, rather than using special syntax
inside of a string (e.g. `["/bar/" :bar]` instead of compojure's `"/bar/:bar")
* use a nested vector with a regex (e.g. `[".*" :rest]`) to match a regex
* `context` macro does not provide a binding form for request vars like compojure's
Other than those differences, the API should be very close to compojure's.
You can apply a Ring middlware to all the handlers at the leaves of a route using ```wrap-routes```, which has behaviour analagous to its counterpart in compojure. Multiple middlewares can be applied to the same routes, with those applied later wrapped around those applied earlier. This allows you to create multiple routes wrapped with different middleware yet still combine them into one overarching route that can be introspected.
(let [my-routes ...
my-singly-wrapped-routes (wrap-routes my-routes inner-middleware)
my-doubly-wrapped-routes (wrap-routes my-singly-wrapped-routes outer-middleware)
my-other-routes ...
my-wrapped-other-routes (wrap-routes my-other-routes other-middleware)
my-combined-routes (routes my-doubly-wrapped-routes my-wrapped-other-routes)]
## What does Comidi do?
Comidi provides some macros and functions that are intended to feel very similar
to the compojure routing macros / functions, but under the hood they construct,
compose, and return bidi route trees rather than compojure handler functions.
This way, you can define your routes with almost exactly the same syntax you've
been using (or port over a compojure app with minimal effort), but end up with
an introspectable route tree data structure that you can do all sorts of cool
things with before you wrap it as a ring handler.
Under the hood: comidi uses bidi to do all of the work for routing, and uses
a few functions from compojure to maintain some of the nice syntax. Specifically,
it uses compojure's route destructuring to bind local variables for parameters
from the requests, and it uses compojure's "rendering" functions to allow you
to define the implementation of your route flexibly (so, just like in compojure,
your route definition can be a literal return value, a reference to a function,
a call to a function, a String, etc.)
Comidi also provides a function called `route-metadata`. This function
walks over your route tree and generates a metadata structure that gives you
information about the all of the routes; e.g.:
(-> (route-metadata (routes
(GET "/foo" request
(PUT ["/bar/" :bar] [bar]
(str "bar: " bar))))
[{:route-id "foo", :path ["" "/foo"], :request-method :get}
{:route-id "bar-:bar", :path ["" "/bar/" :bar], :request-method :put}]
Comidi also provides its own middleware function, `wrap-with-route-metadata`. If
you use this middleware, your ring request map will be supplemented with two
extra keys: `:route-metadata`, which gives you access to the metadata for all of
the routes in your route tree, and `:route-info`, which tells you which of those
routes the request matches. e.g.:
(let [my-routes (routes
(ANY "/foo" request
{:route-info (:route-info request)}))
handler (-> my-routes
(wrap-with-route-metadata my-routes))]
(:route-info (handler {:uri "/foo"}))))
{:route-id "foo", :path ["" "/foo"], :request-method :any}
## Trapperkeeper / Metrics Integration
The [`trapperkeeper-comidi-metrics`]( contains some middleware that will automatically generate and track [metrics]( for all of the routes in your comidi/bidi route tree, as well as easy integration into [`trapperkeeper`](
## What's next?
* API docs: looking into swagger integration. I could swear I found some bidi-swagger
bindings somewhere a while back, but am not finding them at the moment. It
might be possible to re-use some of the code from `compojure-api` because of
the similarity between the comidi API and the compojure API.
* You tell me! This is pre-1.0 and the API should still be considered fungible.
If there's something you need that this library isn't doing, we can probably
do it. Ping us or submit a PR.
## Support
We use the
[Trapperkeeper project on JIRA](
for tickets on Comidi, although Github issues are welcome too.
lein2 test :all
\ No newline at end of file
(defproject puppetlabs/comidi "0.3.1"
:description "Puppet Labs utility functions and compojure-like wrappers for use with the bidi web routing library"
:url ""
:pedantic? :abort
:dependencies [[org.clojure/clojure "1.7.0"]
;; begin version conflict resolution dependencies
[clj-time "0.10.0"]
;; end version conflict resolution dependencies
[bidi "1.23.1" :exclusions [org.clojure/clojurescript]]
[compojure "1.4.0"]
[prismatic/schema "1.0.4"]
[puppetlabs/kitchensink "1.1.0"]]
:deploy-repositories [["releases" {:url ""
:username :env/clojars_jenkins_username
:password :env/clojars_jenkins_password
:sign-releases false}]])
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment