Re: Full stack Clojure web/REST framework - is there any mileage in it?

2,779 views
Skip to first unread message

James Reeves

unread,
Jan 11, 2013, 12:12:43 PM1/11/13
to clo...@googlegroups.com
On Friday, January 11, 2013 4:52:05 PM UTC, Paul Umbers wrote:

For example, the latest vesion of Compojure (1.1.3) uses Ring 1.1.5 and not the latest version of Ring (1.1.6) which has significantly better util functions available - but I can't use them until Compojure catches up.

Ring 1.1.6 doesn't have any new functions - it's just a patch release. You're thinking of Ring 1.2.0-SNAPSHOT, which should be released within the next month, and will go into beta soon.

Both Ring and Compojure use semantic versioning (http://semver.org/), so Ring 1.2.0 is backward compatible with Ring 1.1.0. This means that you can quite happily use Compojure 1.1.3 with Ring 1.2.0-SNAPSHOT if you so desire.

Semantic versioning solves a lot of the problems you describe, because if a library depends on version 1.0, you know it will work with version 1.1, 1.2, and so forth. Only major versions, such as a leap from 1.5 to 2.0, have breaking changes.

- James

Paul Umbers

unread,
Jan 11, 2013, 1:08:41 PM1/11/13
to clo...@googlegroups.com
My oopsie. You're right, it is 1.2.0. I was looking at the current head of master, which I guess is 1.2.0-SNAPSHOT.

As long as all projects stick to semantic versioning (a lot do), that problem is not so great.

The other problem though is that of which libraries to choose for a particular function. I understand the choice is pretty wide, and that's a good thing to some extent, but it means anyone new to Clojure has to evaluate and choose almost every library they could use - which takes time & effort. If I want to build a web app/service with Java I know I can just go to Spring and it will have pretty much everything I need - tested & compatible. The choice almost becomes a no-brainer. I don't have that same ease of use with Clojure - if someone asked me to build a web app or service now (commercially, so I'm on the Client's clock) I would have to factor in a significant amount of time to choose, test & evaluate frameworks.

I guess that kind of ease-of-use comes from maturity, and Clojure is still relatively immature compared with Java. But then Scala is roughly the same age and they have TypeSafe which, as a full-stack, has a more certain "feel" to it than having to cherry-pick individual Clojure libraries (albeit those that have become de facto standards).

Still, clients pay me to know this stuff, and that was one of the reasons for doing the project - to learn what works, what doesn't and how to go about it.

Sean Corfield

unread,
Jan 11, 2013, 1:25:03 PM1/11/13
to clo...@googlegroups.com
I think there's a philosophical bent in the Clojure community toward
small, composable libraries, rather than monolithic pre-built
combinations - across all domains. This has come up in discussions
before, mostly around the "full-stack web framework" issue, and the
consensus each time seems to be we're better served by doing a
mix'n'match from the available libraries.

Scala is aimed much more squarely at the enterprise world of Java,
which in turn is much more inclined toward the full-stack approach.

FWIW, I ported my mature, popular, convention-based MVC framework FW/1
from CFML to Clojure and even tho' it's nowhere near full-stack, in
the Clojure world it's already far beyond the norm of small,
composable libraries, as it "bundles" Ring and Enlive and has its own
route processing. In the CFML world, FW/1 was a reaction to the large,
full-stack frameworks inspired by Spring, Rails etc, and those CFML
frameworks have routing, security, DI/AOP, ORM, environment control,
logging, test generation and all sorts of things built in... hundreds
of files, tens of thousands of lines of code, massive documentation
and so on. Even FW/1 (for CFML) has routing, some DI and environment
control all built in! FW/1 for Clojure has no DI nor environment
control (although that probably will get added at some point). I'm
somewhat allergic to ORM, favoring thin, simple data mappers instead
:)

Sean
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@googlegroups.com
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> clojure+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en



--
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)

Herwig Hochleitner

unread,
Jan 11, 2013, 2:17:35 PM1/11/13
to clo...@googlegroups.com
IMO there is little value in big dependency hair-balls and gui tools leakily abstracting devop taks.

There is, however, value in curated sets of independent libriaries that work well together. Also in having declarative syntax available for common tasks.
Still IMO, Clojure's web story is still somewhat lacking on those. More specifically in in environment integration, since ring does a great job for binding application components.

Lately I'm trying to push all code that deals with environment and project configuration into leiningen plugins.
I think together with project templates, that can be a great way to get more of the convenience of your classic framework.

kind regards

Dmitri

unread,
Jan 11, 2013, 4:18:27 PM1/11/13
to clo...@googlegroups.com
I think a lot of the issues can be addressed via a good template which sets up all the boiler plate, demonstrates idiomatic usage, and defaults to some common libraries. I'm actively working on filling this gap with the Luminus, which aims to make it easy to get rolling, and sets up all the basic things like sessions, static resources, packaging, etc.

On Friday, January 11, 2013 11:52:05 AM UTC-5, Paul Umbers wrote:

I've been experimenting with Clojure web services recently, and posting the work on GitHub and my blog.

When putting this test app together, it occurred to me that most other languages have a full-stack API available which makes life easier when it comes to making decisions about which libraries/APIs/frameworks to use. It also reduces the possibility of "impedance mismatch" between the libraries. For Java, you can use Spring (or any one of a dozen or more other popular frameworks), for Scala there's Typesafe, and so on. Clojure has Compojure, Ring, several logging, validation and database libraries, and they can be used together but they don't constitute a coordinated full stack - and that creates issues.

For example, the latest vesion of Compojure (1.1.3) uses Ring 1.1.5 and not the latest version of Ring (1.1.6) which has significantly better util functions available - but I can't use them until Compojure catches up. By the time you add logging, validation, data access, etc the odds of a mismatch between these libraries goes up dramatically.

This is a concern, because these mismatches must be worked around in my code and are likely to break as the libraries are upgraded in future versions. So, I'm having to spend my time maintaining what are essentially "patches" for third-party libraries just so that they work together.

Now, it may not be the best decision to try to put together a true full-stack framework from scratch, but is it worth choosing a bunch of existing frameworks and coordinating their releases - in much the same way as Eclipse coordinates plugin releases for major releases - so that putting together a full-stack app becomes easier?

Projects taking part in the "meta-project" will work together to harmonize their functionality & APIs, and coordinate their development cycles & releases so that the meta-framework remains consistent and easily usable.

Is this another barrier to adoption the Clojure community can remove? Is this even a barrier? Am I missing something?

Thoughts?

[Also posted to http://www.reddit.com/r/Clojure]

Marko Topolnik

unread,
Jan 11, 2013, 4:27:11 PM1/11/13
to clo...@googlegroups.com

I'm somewhat allergic to ORM, favoring thin, simple data mappers instead :)

You are not alone: ORM, together with the idea of a "persistent state manager" is a beautifully paved road---to hell. In the prototype phase it gives the impression of an ideal solution: code looks just like it's operating on plain memory objects. What could ideally be milliseconds, ORM turns them into tenths of a second, and this doesn't get anyone worried. Then, when you have the whole project committed to ORM and start working on some really tough requirements---and only those are the ones that truly add value to your product, tasks that could take a tenth of a second turn into show-stopping pauses of ten seconds and more.

Now, if you are using a full-stack framework like Rails, you are pretty much stuck with its ORM solution, like it or not; with Clojure's mix-and-match approach, you just find what you are more comfortable with.

Eric MacAdie

unread,
Jan 11, 2013, 4:33:15 PM1/11/13
to clo...@googlegroups.com
Is there a page that gives "Clojure web recipes"? It would be great for beginners if you could have one place that says "To make a web app, you need X, Y and Z, and here are libraries that fulfil each of these needs."

- Eric MacAdie

Marko Topolnik

unread,
Jan 11, 2013, 4:58:16 PM1/11/13
to clo...@googlegroups.com
There's a pretty good page at heroku. There's also this classic page: aging, but still very relevant.

Eric MacAdie

unread,
Jan 11, 2013, 5:56:26 PM1/11/13
to clo...@googlegroups.com
Thanks for the info. I will look this over, and perhaps finally build my world-changing Clojure app. Or maybe just "Hello World."

- Eric MacAdie

Paul Umbers

unread,
Jan 11, 2013, 6:05:05 PM1/11/13
to clo...@googlegroups.com
On Friday, 11 January 2013 12:17:35 UTC-7, Herwig Hochleitner wrote:

There is, however, value in curated sets of independent libriaries that work well together. Also in having declarative syntax available for common tasks.
Still IMO, Clojure's web story is still somewhat lacking on those. More specifically in in environment integration, since ring does a great job for binding application components.


I would have to agree with this, because it's exactly the kind of thing I was thinking of in the original post. Eclipse is made up of a core application and a large set of plugins. While the individual plugin developers are free to develop as they see fit, they have all chosen to join together to produce at least one stable, consistent release per year where everything just works together nicely (well, OK, maybe not so nicely with Juno). I know the Clojure philosophy is, as Sean mentioned above, to build from small composable libraries, but to foster increased adoption in enterprise environments there's something to be said for a quick, easy start.

I think maybe a combination approach of curated library versions (that work well together) and a comprehensive set of templates would go a long way towards easing adoption.

I get the feeling we're almost there with Leiningen templates and the more mature libraries (like Compojure/Ring), and it would just take some buy-in and coordinated effort making it happen.

Matt

unread,
Jan 11, 2013, 7:00:02 PM1/11/13
to clo...@googlegroups.com
Though the Clojure community has traditionally gone with smaller libraries rather than large frameworks, there is a full-stack web framework for Clojure called Conjure: https://github.com/macourtney/Conjure

Sean Corfield

unread,
Jan 11, 2013, 8:04:01 PM1/11/13
to clo...@googlegroups.com
You could just do:

lein new fw1 myapp
cd myapp
lein run

assuming you have nothing running on port 8080 already - otherwise:

PORT=8123 lein run

Noir also has a simple Leiningen template (although Noir is deprecated now):

lein new noir noirapp
cd noirapp
lein run

(same caveat applies regarding ports)

Tim Cross

unread,
Jan 11, 2013, 8:58:02 PM1/11/13
to clo...@googlegroups.com
A good thought/discussion provoking post, thanks.

I find myself between two camps here. On one side and coming from the position of both learning Clojure and coming back to web development after a long period of mainly working on large backend database apps, the suggestion of a nicely bundled and complete clojure web framework is appealing. 

On the other hand, having been required to become familiar with some frameworks, such as spring, being forced to search through large quantities of documentation and then finding 80% of what it offered was not relevant to what I needed for my application, I'm far less enthusiastic regarding complete frameworks. 

I think there may be two different requirements here which need addressing. The first is for those, often new to clojure, who would like to get up and running fast. They have a new idea to start developing and don't want to spend hours evaluating lots of different, but outwardly similar libraries - especially as they may not yet have the knowledge to easily make such decisions. The second requirement is for more experienced or knowledgable devs or those who have a well defined design who just need to know which specific libraries to use. I suspect that as you gain web dev experience with clojure, you will move more twards the second group. If this is the case, complete frameworks are likely to be of only limited benefit while you become familiar and experienced. This may asiist adoption to some degree. However, as individuals become more experenced and accustomed to a more clojure style philosophy of fewer and more specific libraries for a task, they will likely move away from the framework. Unfortunately, this may have a detremental impact on the maintenance of such a framework as it may be difficult to attract or retain interest as experience grows. 

I think possibly the best way to assist adoption and also provide valuable content for more experienced developers are things like case studies, examples and reviews which cover the various libraries and their use. Example dependency templates etc may also be useful. Blogs such as yours, where you document your experiences and give examples are very valuable. Articles like the hooroku one or Andrew Brehaut's one are extremely useful and valuable. Possibly what would be very valuable would be one consolidated place where all this valuable information could be found. Someone interested in clojure and web development could just go to a single place and find a majority of the good articles, case studies, overviews and evaluation of web dev relevant libraries and techniques/idioms for Clojure. Ideally, this would just be part of another well know Clojure documentation site. 

Tim

John Gabriele

unread,
Jan 12, 2013, 2:08:56 PM1/12/13
to clo...@googlegroups.com
On Friday, January 11, 2013 4:33:15 PM UTC-5, Eric MacAdie wrote:
Is there a page that gives "Clojure web recipes"? It would be great for beginners if you could have one place that says "To make a web app, you need X, Y and Z, and here are libraries that fulfil each of these needs."

Malcolm Sparks

unread,
Jan 12, 2013, 8:51:59 PM1/12/13
to clo...@googlegroups.com
The Clojure tradition of mixing-and-matching small libraries rather than relying on large frameworks like Spring did not emerge by accident. The Java language itself causes library authors to create their own types thereby creating an impedance mismatch with other libraries. Spring (and similar frameworks) have evolved to address these issues, using clever design patterns such as interface adaptation. In contrast, Clojure libraries simply use common data structures (maps, sequences, sets) and Clojure itself has all the functions to convert between them where necessary. The result is that Clojure libraries integrate with each other relatively seamlessly without the need for frameworks like Spring. In other words, the very existence of Spring and other 'compendium' frameworks in the Java world is evidence that a lot of work is required to get Java libraries to work together. The absence of equivalents in the Clojure world is something that we should be very happy about. When you choose a compendium framework, you have to work with whatever libraries have been chosen for you by the framework provider, and hope that the doors you want to walk through are unlocked prior to your arrival. All too often they are not.

I've long felt that large platforms like Spring, Eclipse and even the JDK itself are a trade-off between the benefits of ease-of-use with the sacrifice of future innovation - platforms give incumbent libraries a premature monopoly on a functional area, thereby stifling competition from a potential worthy successor library. What I like about the Clojure eco-system is that, to a large extent, no such monopolies have emerged, there is a truer meritocracy because it is possible for libraries to emerge that provide a better or alternative approach to existing ones - so Ring, Aleph, Hiccup, Enlive, Compojure, Moustache and Liberator (to name but a few) can all peacefully co-exist. Innovative new libraries crop up all the time - so quickly it's almost hard to keep up! In which case, we shouldn't confuse frameworks with simple collections of libraries that some curator has verified work together. This is akin to the function that GNU/Linux distributions perform and there is definite value, especially for beginners, in the community shaping these collections.

Marko Topolnik

unread,
Jan 13, 2013, 9:09:52 AM1/13/13
to clo...@googlegroups.com
Great points. Also take RoR as an example: ruby, dynamic as it may be, still relies on the notion of a class as code owner which means that the class is the namespacing unit for all code that wants to participate in operating on a specific data structure, such as a hash or array. 

After 20-30 years of intensive experience with the concept of encapsulation, the final verdict is that it was a great idea for in-house, monolithic projects of the 80's, but is an annoying impediment in the modern world of composable open-source. 

This difference is akin to the difference between Unix's concept of small tools operating on the common data format as opposed to plugins contributed to all-encompassing environments, a typical scenario on Windows.

Softaddicts

unread,
Jan 13, 2013, 10:28:38 AM1/13/13
to clo...@googlegroups.com
+1, excellent summary of the key points.

We got rid of Spring, Hibernate et cie for the same reasons. They were somewhat
needed in Java but in Clojure we found that they were cumbersome to use and
brought little value.

We realized along the way that some generated Java code (Hibernate is a good
example) was buggy and needed to be maintained by hand.

If even the generated code to glue things together is buggy, were is the gain ?
You end up having to maintain it...

We cut our backend code by a magnitude of more than 15 times by switching to 100%
Clojure and getting rid of the frameworks. Now down to 15000 sloc and less
dependencies to track...

Luc P.


> The Clojure tradition of mixing-and-matching small libraries rather than
> relying on large frameworks like Spring did not emerge by accident. The
> Java language itself causes library authors to create their own types
> thereby creating an impedance mismatch with other libraries. Spring (and
> similar frameworks) have evolved to address these issues, using clever
> design patterns such as interface adaptation. In contrast, Clojure
> libraries simply use common data structures (maps, sequences, sets) and
> Clojure itself has all the functions to convert between them where
> necessary. The result is that *Clojure libraries integrate with each other
> relatively seamlessly without the need for frameworks like Spring*. In
> other words, the very existence of Spring and other 'compendium' frameworks
> in the Java world is evidence that a lot of work is required to get Java
> libraries to work together. The absence of equivalents in the Clojure world
> is something that we should be very happy about. When you choose a
> compendium framework, you have to work with whatever libraries have been
> chosen for you by the framework provider, and hope that the doors you want
> to walk through are unlocked prior to your arrival. All too often they are
> not.
>
> I've long felt that large platforms like Spring, Eclipse and even the JDK
> itself are a trade-off between the benefits of ease-of-use with the *sacrifice
> of future innovation* - platforms give incumbent libraries a *premature
> monopoly* on a functional area, thereby stifling competition from a
> potential worthy successor library. What I like about the Clojure
> eco-system is that, to a large extent, no such monopolies have emerged,
> there is a truer meritocracy because it is possible for libraries to emerge
> that provide a better or alternative approach to existing ones - so Ring,
> Aleph, Hiccup, Enlive, Compojure, Moustache and Liberator (to name but a
> few) can all peacefully co-exist. Innovative new libraries crop up all the
> time - so quickly it's almost hard to keep up! In which case, we shouldn't
> confuse frameworks with simple collections of libraries that some curator
> has verified work together. This is akin to the function that GNU/Linux
> distributions perform and there is definite value, especially for
> beginners, in the community shaping these collections.
>
>
> On Friday, 11 January 2013 16:52:05 UTC, Paul Umbers wrote:
> >
> > I've been experimenting with Clojure web services recently, and posting
> > the work on GitHub <https://github.com/3rddog/doitnow> and my blog<http://internistic.blogspot.ca/search/label/clojure>
> > .
> >
> > When putting this test app together, it occurred to me that most other
> > languages have a full-stack API available which makes life easier when it
> > comes to making decisions about which libraries/APIs/frameworks to use. It
> > also reduces the possibility of "impedance mismatch" between the libraries.
> > For Java, you can use Spring (or any one of a dozen or more other popular
> > frameworks), for Scala there's Typesafe, and so on. Clojure has Compojure,
> > Ring, several logging, validation and database libraries, and they can be
> > used together but they don't constitute a coordinated full stack - and that
> > creates issues.
> >
> > For example, the latest vesion of Compojure (1.1.3) uses Ring 1.1.5 and
> > not the latest version of Ring (1.1.6) which has significantly better util
> > functions available - but I can't use them until Compojure catches up. By
> > the time you add logging, validation, data access, etc the odds of a
> > mismatch between these libraries goes up dramatically.
> >
> > This is a concern, because these mismatches must be worked around in *my*code and are likely to break as the libraries are upgraded in future
> > versions. So, I'm having to spend my time maintaining what are essentially
> > "patches" for third-party libraries just so that they work together.
> >
> > Now, it may not be the best decision to try to put together a true
> > full-stack framework from scratch, but is it worth choosing a bunch of
> > existing frameworks and coordinating their releases - in much the same way
> > as Eclipse coordinates plugin releases for major releases - so that putting
> > together a full-stack app becomes easier?
> >
> > Projects taking part in the "meta-project" will work together to harmonize
> > their functionality & APIs, and coordinate their development cycles &
> > releases so that the meta-framework remains consistent and easily usable.
> >
> > Is this another barrier to adoption the Clojure community can remove? Is
> > this even a barrier? Am I missing something?
> >
> > Thoughts?
> >
> > [Also posted to http://www.reddit.com/r/Clojure]
> >
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@googlegroups.com
> Note that posts from new members are moderated - please be patient with your first post.
> To unsubscribe from this group, send email to
> clojure+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
--
Softaddicts<lprefo...@softaddicts.ca> sent by ibisMail from my ipad!

kovas boguta

unread,
Jan 13, 2013, 8:07:00 PM1/13/13
to clo...@googlegroups.com
I think there is value, but we as a community are not yet ready for it.

The problem is that the "full stack" endgoal is itself shifting in
definition, towards single-page apps.

There is not much appetite for the creation of a RoR clone, when the
landscape in which RoR was created has shifted so much.

The biggest piece missing for a full stack solution in clojure is the
client-side solution. There has yet to emerge a dominent client-side
cljs library or paradigm. And without that, the full-stack solution is
not that full.

With that in place (and I'm confident it will come in 2013), what I'd
like to see is an end-to-end solution that puts immutability first,
including on the database side. We have datomic, but we also have the
principles to implement a proper data model within the context of
traditional databases.


On Fri, Jan 11, 2013 at 11:52 AM, Paul Umbers <paul....@gmail.com> wrote:
> I've been experimenting with Clojure web services recently, and posting the
> work on GitHub and my blog.
>
> When putting this test app together, it occurred to me that most other
> languages have a full-stack API available which makes life easier when it
> comes to making decisions about which libraries/APIs/frameworks to use. It
> also reduces the possibility of "impedance mismatch" between the libraries.
> For Java, you can use Spring (or any one of a dozen or more other popular
> frameworks), for Scala there's Typesafe, and so on. Clojure has Compojure,
> Ring, several logging, validation and database libraries, and they can be
> used together but they don't constitute a coordinated full stack - and that
> creates issues.
>
> For example, the latest vesion of Compojure (1.1.3) uses Ring 1.1.5 and not
> the latest version of Ring (1.1.6) which has significantly better util
> functions available - but I can't use them until Compojure catches up. By
> the time you add logging, validation, data access, etc the odds of a
> mismatch between these libraries goes up dramatically.
>
> This is a concern, because these mismatches must be worked around in my code

edw...@kenworthy.info

unread,
Apr 16, 2013, 7:03:46 AM4/16/13
to clo...@googlegroups.com
I'm a bit curious. My immediate reaction was to ask what you use instead of Spring (none?), Hibernate (datomic?) and what did you use to provide the plumbing for web apps (assuming you needed it and didn't just write it all from scratch).

My second thought was then what is the difference between a framework like Spring and a stack like the one I am assuming you used if it were documented and became a de facto framework?
Reply all
Reply to author
Forward
0 new messages