I don't know that I'll be writing entire web applications in Clojure
any time soon but I expect to be using Clojure in some form from
(essentially) Java-based web applications some time soon, much as I
currently use Groovy and/or Scala for parts of a web application. I'll
be interested in both the easiest and most performant ways to use
Clojure code from something Java based. FWIW, I use CFML (running on
Railo, a free open source JBoss community project, that compiles CFML
down to Java bytecode and runs in a Servlet container) as my primary
web templating / scripting language right now and drop down to other
languages where useful / appropriate.
Looking forward to hearing how others are doing web development with
Clojure! Thanx for kicking off this thread James.
--
Sean A Corfield -- (904) 302-SEAN
Railo Technologies, Inc. -- http://getrailo.com/
An Architect's View -- http://corfield.org/
"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood
First, thank you for all of your work in this area. It is greatly
appreciated. My answers follow:
1. DocuHarvest ( https://docuharvest.com ), which I've already talked
about here. Broadly speaking, it extracts data from documents, and
it's just getting started.
2. Relevant to web development, DocuHarvest uses compojure 0.3.x
(modified to suit clojure 1.2 HEAD), HEAD of enlive and clutch, spring-
security v3, jetty for local development, Tomcat for staging and
production environments, and enclojure's REPL server library in all
environments.
3. Compojure gets me very close to the metal, or as much as one can be
w.r.t. HTTP. Middleware is the pleasant superset of all other flavors
of web request handling; helluva lot of power there with very little
cost. Mix that with a solid REPL (via enclojure for me) for zero-
turnaround development, and I'm very, very happy.
4. I want to be able to define HTTP APIs more concisely. compojure-
rest (http://github.com/ordnungswidrig/compojure-rest) and clj-conneg (http://github.com/rnewman/clj-conneg
) are pointing the way towards what the response to that looks like, I
think.
The most common issues I see are related to packaging and deployment.
I think this could probably be made easier for those that aren't
familiar with the java way of doing webapp deployment. Getting people
familiar with the (honestly simple) mostly-canned tooling solutions
that are out there would help, but short of that, perhaps a pre-
compiled servlet (configured via a web.xml file that defines the top-
level route that all requests are dropped into, etc) would help.
Building the war file would still be necessary, but that's when-in-
Rome territory. IMO, every time someone deploys a compojure app via a
hacked-up shell script and embedded jetty, a kitten is killed. ;-)
5. I better quit while I'm ahead for today!
And no, thank you, and everyone else that's made web development with
Clojure as pleasant as it is! :-D
- Chas
> 1. Have you written, or are you writing, a web application that uses
> Clojure? What does it do?
I'm writing cloudhoist.com, a cross cloud management console and api, that
lets you start and stop nodes on Amazon, Rackspace, etc, configure them
with your favourite stacks (eg, tomcat, mysql, couchdb), deploy you apps
and carry out admin actions.
> 2. Which libraries or frameworks are you using? Which versions?
Ring, moustache, enlive, scriptjure, clutch. All latest versions. Jetty,
tomcat, nginx.
> 3. What made you choose Clojure to develop web applications in? What
> are the strengths of Clojure web development?
It's a lisp, with all that entails, and it deploys nicely on the JVM.
> 4. What do you think are the current weaknesses of web development in
> Clojure? What could be improved?
I am interested in using clojure for client side coding. Ring friendly
authentication and authorisation libs would be nice (I rolled my own). I
miss rails' named routes, but am sure something better will materialise
for clojure.
> 5. Anything else you want to comment on?
Thanks to everyone for their work in this area!
--
Hugo Duncan
I am and have been extending an existing production java web
application environment with all new server work now being done in
clojure. It is a complex jvm server running tomcat and other threaded
proprietary services and integration paths into back-end feed systems.
Front-end stuff, previously jsp is now all being replaced by
javascript/jquery and ajax.
I am also working on a netty/clojure setup to create some distributed
event-driven processes for scaling up the services and in the future
replacing most of the the above in-jvm/threaded routines. Down the
line I hope to release some of this as open-source.
> 2. Which libraries or frameworks are you using? Which versions?
In the early stages, I tried compojure, but my setup needed much
tighter java/clojure interop and hence most of my effort has gone in
that direction. I do use enlive, joda-time, jfreechart and a bit of
clj-html/hiccup. Java libs - tomcat, log4j, apache-commons,
postgresql-jdbc. Plus many person-years of various proprietary java
and unix utility libraries for (hosted) infrastructure and operations
management. Generally I have found most of the other java frameworks
too "heavy" for my rather close-to-the-wire preferences.
> 3. What made you choose Clojure to develop web applications in? What
> are the strengths of Clojure web development?
I learnt a bit of lisp way back but career-wise all my work has
generally been c/c++/java based. I spent about 9 months with scala
hoping for an improved jvm capability, but found it too tedious when
trying to work on the complex setup mentioned above. Happened upon
clojure 18 months ago and this was the holy-grail incarnate. You
really can get pretty close to expressing directly what's in your
mind. Haven't looked back since.
> 4. What do you think are the current weaknesses of web development in
> Clojure? What could be improved?
Plenty of room for event-driven techniques, javascript/jquery
generation stuff, distributed processing, disk-based persistence, etc.
The new protocols/types/records and the coming primitives improvements
are very exciting.
> 5. Anything else you want to comment on?
Performance, performance, performance and by the way, performance.
When you run server applications, especially non-blocking, event
driven, every little milli-second per function counts hugely when
scaling up to thousands, tens of thousands or more asynchronously
accessed services. Clojure has done wonders in eliminating boilerplate
tedium and maintenance grovel, so generally I would now like to focus
on improving my reality of 30% coding, 70%
tuning/benchmarking/refactoring.
- Regards, Adrian.
we are currently developing a game server backend using clojure.
> 2. Which libraries or frameworks are you using? Which versions?
>
we are using grails for the web app aspect, and uses the grails
plugin to call clojure code.
> 3. What made you choose Clojure to develop web applications in? What
> are the strengths of Clojure web development?
in this case, we are really using grails for the web aspect, but uses
clojure for AI and game logic. clojure is very good at that.
>
> 4. What do you think are the current weaknesses of web development in
> Clojure? What could be improved?
>
too many scattered libraries and approaches. For me, it's about
problem solving. I would like to be able to just grab something, and
get it started. Right now, if a new clojure user ask, I want to develop
a web app, what should I use? Compojure? Ring? What template
system should I use? enlive? str html? hiccup? How do you deal with
database? clj-record? clojuresql? How do you make outbound
REST request?
> 5. Anything else you want to comment on?
clojure is still young. I hope in time, a web dev approach that's
more clojure-ish. lift has done a good way to show what a web
framework using scala and functional style would look like.
I look forward to see something like this for clojure one day.
--
Omnem crede diem tibi diluxisse supremum.
- Chas
> --
> 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
> (def stuff {:key1 {:item1 {:sub1 val1}})
> (((stuff :key1) :item1) sub1) <------- YUCK
val1
> (rest stuff)
(2 3 4 5)
> (next stuff)
(2 3 4 5) <---- this can be done with rest.
Am 24.06.2010 um 21:12 schrieb Tim Robinson:
> I would like some chaining to less the brackets.
> i.e.
>
>> (def stuff {:key1 {:item1 {:sub1 val1}})
>> (((stuff :key1) :item1) sub1) <------- YUCK
> val1
>
> Instead do this:
>> stuff:key1:item1:sub1
> val1
(-> stuff :key1 :item1 sub1)
> Also, some of the function names don't make sense:
> (def stuff (list 1 2 3 4 5))
>> (rest stuff)
> (2 3 4 5)
>> (next stuff)
> (2 3 4 5) <---- this can be done with rest.
next and rest are not the same. See http://clojure.org/lazy.
Sincerely
Meikel
Am 24.06.2010 um 22:07 schrieb Tim Robinson:
> Along this vein, I find the documentation is great, but a little hard
> to navigate around.
http://richhickey.github.com/clojure
http://richhickey.github.com/clojure-contrib
Note the branch links on the top left.
Sincerely
Meikel
roman candle is a web app designed to let me control X10 plc
components from any web-capable device, using the X10 firecracker
controller. It's still in very early development, and hasn't been
given much attention lately. The intent is more to learn about clojure
rather than provide a distributable utility.
> 2. Which libraries or frameworks are you using? Which versions?
I've always been impressed by the Seaside framework, if only it
weren't tied to smalltalk. While there are now some C/C++ frameworks
along this line, there don't appear to be any available for Java, much
less clojure. So I'm developing a small framework - bitchen' - in
parallel with roman candle. This is also more pedagogical than
production, in that it's not at all clear how to "port" the seaside
model from an OO language to a functional/immutable one like Clojure.
Should I decide that I'm going to get serious about clojure, this
might eventually become a full-fledged framework.
> 3. What made you choose Clojure to develop web applications in? What
> are the strengths of Clojure web development?
Wanting to provide a better answer to that question. Clojure itself is
interesting for it's LISPyness, concurrency facilities, and tight
integration with the JVM.
> 4. What do you think are the current weaknesses of web development in
> Clojure? What could be improved?
The tight integration with the JVM. I believe it's brought more pain
than happiness.
> 5. Anything else you want to comment on?
Not really.
<mike
--
Mike Meyer <m...@mired.org> http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.
O< ascii ribbon campaign - stop html mail - www.asciiribbon.org
I'm writing a framework, Cascade.
http://wiki.github.com/hlship/cascade/
> 2. Which libraries or frameworks are you using? Which versions?
So far, no dependencies ... but I may switch out some ad hoc logic for
stuff from Ring. Even I try not to reinvent the wheel every time!
>
> 3. What made you choose Clojure to develop web applications in? What
> are the strengths of Clojure web development?
I eventually hope to have Cascade handle parallel rendering of the
overall content across multiple threads, which makes sense when
rendering a single view requires multiple database queries that can
execute in parallel.
Partly Cascade exists as a way to learn Clojure fully, even if I don't
use Cascade professionally in the meantime. For most projects, I'll
keep using Tapestry :-)
However, I do really like having the template be Clojure forms.
Unlike Compojure/Hiccup, the Cascade templates are rendered to an
intermediate DOM format that can be manipulated before final streaming
as text. There are advantages to this, learned from Tapestry, in terms
of coordinating individual rendering functions (what might be
components in Tapestry) ... especially w.r.t. the inclusion of
stylesheets and JavaScript libraries. These are done declaratively in
Cascade.
For the most part, it was easier to get live reloading working in
Cascade than in Tapestry (in Tapestry, change a class, it is reloaded.
In Cascade, change a namespace, it is reloaded). There are still some
issues, especially when there are errors in the reloaded namespace.
>
> 4. What do you think are the current weaknesses of web development in
> Clojure? What could be improved?
Clojure's native exception reporting is weak! Cascade improves on
this in a couple of ways (some of which may have been picked up by
Compojure).
>
> 5. Anything else you want to comment on?
For what I've heard, I'm not the first person to implement an
application in Cascade, which floors me. It's really at the research
project level right now, but I do like what I've managed so far.
>
> Please reply to this thread with your answers, and thank you very much
> in advance for your time. I really appreciate any feedback you can
> provide.
>
> - James
>
> --
> 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
--
Howard M. Lewis Ship
Creator of Apache Tapestry
The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!
I considered it but I needed comet support and didn't want to roll my own
when my practical clojure experience was limited. I think that
clojure would be an excellent platform for what I was planning on doing
but it lacked the comet support I needed so I'm implementing in Seaside
for Gemstone's Smalltalk.
--
Ditto. Django's admin tool is something I haven't seen elsewhere, and
it saves me gobs of time. I can't imagine switching to a framework
that doesn't have that. But hypothetically, if Clojure did have
something like that, I'd consider switching.
Another factor to me is the reality of webhosting. There are a number
of webhosting services (e.g., webfaction) that make it super-easy to
get Django, turbogears, cherrypy, rails, etc. up and running with
one-click installers and very detailed tutorials. On the other hand,
Java-based servers usually require much more knowledge to deploy, and
usually require more memory than the cheapest plans offer. I'd
probably be unlikely to switch to Clojure for webhosting without
detailed instructions on how to deploy on a well-known, inexpensive
hosting service (like webfaction).
I'm going to try and address some of the issues people have raised. If
I've missed any big ones, feel free to shout louder :)
@Joost
Could you send me an email with the i18n patches you had to make to
Compojure/Ring?
@Chas
I think we probably need a high-level way of exposing a type as a HTTP
resource. I haven't thought about this much, but it's certainly a hole
that isn't quite filled by currently available libraries.
@Chas, @Brian, @Brenton
Deployment is also an issue. Perhaps we need a Leiningen plugin that
would automatically generate an AOTed HttpServlet, given a :handler
key in defproject that designates the main handler function.
Another option is to bypass the whole idea of Java servlet containers
and devise some lightweight Clojure solution. I guess some people will
like that idea, whilst others will shudder at the idea of reinventing
a well-used wheel.
@Hugo
I agree that a standard authentication and authorization library would
be good. With OpenID, OpenAuth, etc. authentication is becoming quite
complex, and login pages are becoming quite uniform. It would be nice
to have some middleware that would automatically provide this sort of
thing.
Named routes may be something I could integrate into Compojure. I'd
have to think of a good way of doing it.
@Adrian
One thing Ring and Compojure are lacking are some good benchmarks.
I'll have to see about making some, unless anyone wants to volunteer?
@Jimmy, @Chas, @Sean
Websockets/Comet is something that has been mentioned to me a few
times. Websockets are a separate protocol to HTTP, and Comet is
essentially a separate protocol, even if it uses HTTP as a transport
layer. So in the past, my opinion is that normal HTTP should be
handled by Ring, and Websockets/Comet should be handled by something
different.
However, it occurs to me that whilst Websockets and Comet are arguably
not HTTP, they do start out with a normal-looking HTTP request. I
wonder if Ring could accept this initial request, but instead of
returning a standard response map, it returns a message-handling
function.
I'll think about this, then bring it up on the Ring group for further
discussion.
@Wilson, @Daniel, @Mark E
Clojure web development is shaping up to be made up of many small,
interchangeable parts. On the whole, I think this is a good thing. I
don't like the idea of monolithic web frameworks, continually
reinventing the same wheels (routes, templates, ORM). My goal for
Clojure web development is near total interoperability.
But at the same time, it's good to be able to pick something up that
integrates all these small parts together. I think eventually we'll
see larger frameworks emerging for Clojure that just tie a bunch of
low-level libraries together. But I think we're a little way off that
goal.
@Wilson, @Brenton, @j-g-faustus, @Brian, @pavelludiq
I've also started writing a Clojure Web Development book. One of the
problems of having lots of small libraries is that its hard to get an
overview of how one should proceed. The Clojure Web Development book
is an effort to take the reader through the Clojure web development
ecosystem, starting with Ring, but also later covering Compojure,
Hiccup, Enlive, Moustache, Sandbar and others.
I envision this as being similar to the Git community book
[http://book.git-scm.com/]. I've started a Google document for it,
which you can view here:
https://docs.google.com/Doc?docid=0AQqGP1CDN0uIZGhmZjJmcGZfMjNjNHIycGZu&hl=en
At the time of writing, it's in a ***very*** rough state. If anyone
wants to help me out, I'll send them a read-write link they can use to
contribute. When the book is more complete, I'll divide it up into web
pages and put it in a GitHub repository.
@Mark S
Logging is something I've been very interested in at various points in
the past, usually when an application goes wrong in production and I
have to figure out what went wrong!
I think we need to discard the notion that logs should be timestamped
strings outputted to a file. Instead, I think they should be hash-maps
we send to a logging server, which then stores them in a database.
You could then visit the database and say "Show me all exceptions that
occurred for user X". You could then select the field you wanted and
say "Show me all log messages that occurred within the context of the
same request as this exception". This is something that would have
saved me a lot of pain in the past.
You've gotten me thinking of writing something like this, perhaps
using MongoDB or Redis to store the documents, and Compojure to write
a nice web interface for searching/configuring.
@Martin
I've been thinking on and off about how to bind data to a set of
routes. I'll let you know if I come up with anything, and suggestions
are always welcome. I think Allen's "Turtles all the way down" post in
the Compojure group is thinking along the right lines.
@Howard
Exception reporting could be better, I think. Clojure in general tends
to have pretty tangled stacktraces, but perhaps that's just because
it's difficult to distinguish between my libraries and clojure.core
where the exception invariably bubbles up from.
Improvements to the Ring stacktrace middleware might help. Perhaps
also something that automatically logs stack traces.
@Mark E
Hosting facilities will probably improve in future, but I suspect
it'll be a while. I'd personally like something like Heroku, but I
don't think the demand is there to sustain a service like that.
I hope this reply was comprehensive enough. There are a lot of really
useful replies in this thread.
- James
Great idea for a survey!
I'm using Clojure to bootstrap a startup, broadly in the Healthcare
domain. The system we're building comprises a number of components
all implemented in Clojure, one of which is a centralised web server.
The reason we chose Clojure was because it runs on the JVM, and we can
interact easily with lots of legacy systems (Java has the best API's
for interacting with the legacy systems we need). This coupled
equally with Clojure's strong DSL capabilities, and homoiconic syntax
(beyond just macros) are a key motivator for us. I doubt the things
we're doing would be achievable in Scala, Groovy or JRuby in the time
frames we need... Because Clojure seems naturally suited to our
domain problem.
Anyway, the point is that we're using Clojure for non-web reasons, but
have been pleasantly surprised by the web story as it stands...
Though right now (on the web) our needs are pretty basic.
On the web side, we're using Ring and Moustache. We were using
Compojure, but migrated to Moustache as I suspected Compojure was
giving us problems with Clojure 1.2 (which we need for incanter).
Anyway, the problem turned out to be unrelated to Compojure but the
work involved in migrating between Compojure and Moustache was only
about 30 minutes! So in this regard I think the component oriented
approach to web development is working, as you really can swap
components in and out quickly and easily... Something that I think
would be far harder in Ruby (even with Sinatra).
I'm on the fence in the Moustache vs Compojure debate. Both seem very
good. I like how Moustache is more Clojure like. But then I also
like how Compojure is more 'HTTP' like, i.e. it is more apparant that
Compojure is routing HTTP requests than with moustache... but I think
moustache is more flexible.
That said I have two issues with moustache:
1) There are too many equivalent syntactic forms. This can be
confusing, and I think I'd prefer the different syntaxes to have
different semantics.
2) Moustache seems to silently swallow errors... However I haven't
debugged this yet to firmly blame moustache, as it could well be my
code.
Anyway we're not firmly in Moustache camp and might later switch back
to Compojure if it's beneficial.
The web-app UI itself is written in Java as GWT application, that is
compiled into HTML CSS & Javascript, however we write the GWT-RPC
servlets in Clojure, and AOT compile them for wiring into jetty.
This combination works quite well, as we get a blindingly fast UX,
whilst retaining interactive development of both the ajax client and
server side... whilst not worrying too much about cross browser
issues. This said, I'm not completely sold on GWT yet, and we might
consider switching to something else if it proves more capable or
productive.
We use Moustache (and before it Compojure) for routing API style
requests rather than those from the webapp.
The most complex part of our web-application is really the jetty
wiring. Unfortunately because we want to mix both servlets (AOT
compiled GWT RPCServlets) and ring handlers, we can't use the ring
jetty wrapper.
This could be simple if ring provided a means of converting a servlet
into a handler (it already does the other way). This is the feature
I'd most like to see in ring.
We could of course wire the thing together in a web.xml, but IMHO
that's more pain than wiring it in Jetty. Besides, having a REPL
direct into the server is really handy, when you need to interogate
things.
Anyway, I'm *way* more productive in Clojure after a year and a half
than I ever was in Ruby (approx 3-4 years) and Java (more than I care
to count). I love how pragmatic the language is, and how you can
solve a complex problem in 5 lines of expressive code... Not to
mention interactive development, and paredit which makes life coding
way more fun than even Ruby was.
Oh, and also Clojure is fast!! Love it! ... Oh and did I mention how
great incanter is?! :-)
Anyway, thanks again for your devotion to the Clojure community!
R.
On 23 June 2010 22:23, James Reeves <weave...@googlemail.com> wrote:
> Hello there!
>
> Chas Emerick's recent "State of Clojure" survey [http://bit.ly/dtdAwb]
> indicated that a significant proportion of Clojure users are beginning
> to use Clojure for web development. A recent Hacker News posting
> [http://bit.ly/91Bu5J] seems to corroborate these results, with
> several Clojure-based web applications already out in the wild.
>
> As one of the main developers of Ring and Compojure, I'd be very
> interested to hear more about how people are using Clojure to build
> web apps. To this end, I have a few questions I'd like to quiz Clojure
> web developers about:
>
> 1. Have you written, or are you writing, a web application that uses
> Clojure? What does it do?
>
> 2. Which libraries or frameworks are you using? Which versions?
>
> 3. What made you choose Clojure to develop web applications in? What
> are the strengths of Clojure web development?
>
> 4. What do you think are the current weaknesses of web development in
> Clojure? What could be improved?
>
> 5. Anything else you want to comment on?
>
> Please reply to this thread with your answers, and thank you very much
> in advance for your time. I really appreciate any feedback you can
> provide.
>
> - James
>
Sorry, I guess wasn't entirely clear.
The maps would still contain timestamps. My point is that we should
get away from the idea thinking of logs as unstructured text strings.
For example, a typical log message for a web application might look
something like:
{:application "Some app"
:timestamp "20100626T112154Z"
:server-ip "10.23.1.34"
:request-uuid "885902e5-4fd0-43b3-b3d6-8961e8987278"
:session-user-id 102
:level "error"
:message "Inconsistent user data"
:stacktrace ["<line1>" "<line2>" ...]}
Something with lots of juicy information we can filter on, and
something that can be elegantly displayed in a web-based user
interface.
> I prefer files. Using a DB prevents me from using existing powerful
> tools to search and query the logs: vim and emacs.
Databases are usually quite good at querying information as well; that
is something they are designed to do, after all. I believe MongoDB has
support for regular expression searches, so there's not really
anything you can do with a text editor that you can't with a
sufficiently advanced database.
You also get more fine-grained control over storage. For instance, I
might want to have debugging messages expire after five days, but
error messages expire after three months. Or perhaps I want to blind
user information before exposing the logs to developers.
That said, any good logging library has support for multiple back
ends. If you didn't want to write out to a database, you could plug in
your own storage system that divides files up by user ID and date, and
then appends the log messages to a text file.
- James
(We're hiring for this project.)
Jeffrey Straszheim
Senior Software Engineer