Compojure 0.6.0-RC1 released

65 views
Skip to first unread message

James Reeves

unread,
Jan 19, 2011, 10:08:03 PM1/19/11
to Compojure
I've just released the first release candidate for 0.6.0.

There is one breaking change: `routes` and `defroutes` no longer add
parameter and cookie middleware by default.

The default routes middleware was convenient, but caused several
issues and restricted developer choice. So from now on, you'll need to
explicitly add this middleware to your handler.

To make this easier, I've added the compojure.handler namespace. This
contains functions that give your routes standard stacks of
middleware, in the correct order.

The `compojure.handler/api` function adds the wrap-params,
wrap-keyword-params and wrap-nested-params middleware. This function
is useful if you want to create a RESTful API, and you don't require
cookie or session support.

The `compojure.handler/site` function adds all the middleware from
`api`, along with wrap-multipart-params, wrap-cookies and
wrap-session. In other words, the basic middleware you need for a
standard web application.

You may notice that both `site` and `api` have nested keyword
parameters. This means that a standard parameter map like:

{"foo[bar]" "baz"}

It will be turned into a map like:

{:foo {:bar "baz"}}

This is the same syntax for grouping together parameters that is found
in frameworks like Ruby on Rails and Sinatra.

The "vector" bindings for Compojure routes will match either keywords
or string parameters, so you don't have to worry about bindings not
working if you choose not to use keyword parameters.

The next significant change is the introduction of the `context`
macro. You can use this macro to add a common prefix to a bunch of
routes:

(defroutes example
(context "/foo/:id" [id]
(GET "/" [] ...)
(GET "/edit" [] ...)
(POST "/" [] ...)))

The bound `id` parameter is accessible by each of the inner routes.
The context macro adds two additional keys to the request map:
:context and :path-info. The :context key is the path matched by the
context, and the :path-info key is the remaining suffix. If the
path-info is empty, it's set to "/". Routes will match on the
:path-info key first, and then the :uri if the path-info key does not
exist.

So, for example, if the URI being accessed was "/foo/10/edit", then
the context would be "/foo/10" and the path-info would be "/edit".

Finally, I've deprecated the wrap! macro. It's not very idiomatic
Clojure to re-define an existing var, and it doesn't accomplish much
more than the standard -> macro.

- James

Michael Ossareh

unread,
Jan 20, 2011, 1:51:01 PM1/20/11
to comp...@googlegroups.com
On Wed, Jan 19, 2011 at 19:08, James Reeves <jre...@weavejester.com> wrote:
(defroutes example
 (context "/foo/:id" [id]
   (GET "/" [] ...)
   (GET "/edit" [] ...)
   (POST "/" [] ...)))

zomg - I love this!
 

James Reeves

unread,
Jan 20, 2011, 2:38:16 PM1/20/11
to Compojure
On 20 January 2011 03:08, James Reeves <jre...@weavejester.com> wrote:
> I've just released the first release candidate for 0.6.0.

One minor thing I forgot to mention: you can use the :as keyword in
vector bindings to get the full request map, e.g.

(GET "/foo/:id" [id :as request] ...)

This allows you to bind the parameters and any values in the request map:

(GET "/foo/:id" [id :as {cookies :cookies}] ...)

I'm not sure whether "as" is the right word for it, but it has the
same purpose as the :as keyword in normal Clojure bindings.

- James

Vagif Verdi

unread,
Jan 21, 2011, 3:01:30 AM1/21/11
to Compojure


On Jan 20, 11:38 am, James Reeves <jree...@weavejester.com> wrote:
> I'm not sure whether "as" is the right word for it, but it has the
> same purpose as the :as keyword in normal Clojure bindings.
>
> - James

I propose several alternatives :)

(GET "/foo/:id" [id :also {cookies :cookies}] ...)
(GET "/foo/:id" [id :along-with {cookies :cookies}] ...)
(GET "/foo/:id" [id :and-friends {cookies :cookies}] ...)

James Reeves

unread,
Jan 21, 2011, 7:37:17 AM1/21/11
to comp...@googlegroups.com
On 21 January 2011 08:01, Vagif Verdi <vagif...@gmail.com> wrote:
> I propose several alternatives :)
>
> (GET "/foo/:id" [id :also {cookies :cookies}] ...)
> (GET "/foo/:id" [id :along-with {cookies :cookies}] ...)
> (GET "/foo/:id" [id :and-friends {cookies :cookies}] ...)

I was thinking more like :request :)

(GET "/foo/:id" [id :request {cookies :cookies}] ...)

But I'll probably stick with :as for now, because that matches the
normal Clojure bindings:

(GET "/foo/:id" {:as request} ...)
(GET "/foo/:id" [:as request] ...)

- James

Nicolas Buduroi

unread,
Jan 21, 2011, 11:39:11 AM1/21/11
to Compojure
On Jan 19, 10:08 pm, James Reeves <jree...@weavejester.com> wrote:
> I've just released the first release candidate for 0.6.0.
> (defroutes example
>   (context "/foo/:id" [id]
>     (GET "/" [] ...)
>     (GET "/edit" [] ...)
>     (POST "/" [] ...)))

I've been waiting for that since day one! Thanks a lot!!!

Wilson MacGyver

unread,
Jan 21, 2011, 11:59:28 AM1/21/11
to comp...@googlegroups.com
On Wed, Jan 19, 2011 at 10:08 PM, James Reeves <jre...@weavejester.com> wrote:
> The next significant change is the introduction of the `context`
> macro. You can use this macro to add a common prefix to a bunch of
> routes:
>
> (defroutes example
>  (context "/foo/:id" [id]
>    (GET "/" [] ...)
>    (GET "/edit" [] ...)
>    (POST "/" [] ...)))
>

Thank you very much. As I've stated a few times on the mailing list,
it's something
I've wanted for a long time.


--
Omnem crede diem tibi diluxisse supremum.

Luc Prefontaine

unread,
Jan 21, 2011, 12:05:29 PM1/21/11
to comp...@googlegroups.com
Aaaaaah ! What a relief !

We will give it a try in the next couple of weeks, feeling like a hamster in a wheel
these times.

Thank you James.

Luc P.

--
Luc P.

================
The rabid Muppet

Reply all
Reply to author
Forward
0 new messages