4 ms·
Detailed Breakdown of a Clojure Web App
- weavejester 14y agoI have a couple of suggestions. 1. If you return a handler function from a Compojure route, the handler is evaluated with the request. So: (GET "/" request (posts/all request)) Is the same as: (GET "/" [] posts/all) So there's no need for a separate "route" macro. However, passing the full request map is discouraged, because the more information you give a function, the more things can theoretically affect it. Functions should be limited in what they know and what they can do, and this is one of the principles Compojure is designed around. 2. Some of the macros you've written for Korma could be written as functions instead. For example: (defn paginate [query page per-page] (-> query (limit per-page) (offset (dec page)))) (post/all (where conditions) (paginate page per-page))
- nonrecursive 14y agoThank you! And thank you for making such great libraries available. For #1, I definitely started by not passing the full request map but I ended up finding it cumbersome. On the other hand, my code doesn't really need the full request map. I'll have another go at it and see how I can improve things - thanks for the guidance. It feels like a process of over-contraction, then over-expansion. Hopefully I'll find a happy medium. For #2 - thank you! I was trying to work toward something like but couldn't quite get there, so this is great.
- weavejester 14y agoCould you give me an example of a route that was particularly messy if you didn't pass the full request map? Maybe I can suggest a better option (or at least admit defeat :)
- nonrecursive 14y agoYou know, I actually can't think of any. I just ended up writing things the way I did because I anticipated I would want the full request map, but that assumption hasn't born out. Passing params might be a good way to go. I need to go back and change this!
- deleted 14y ago[deleted]
- deleted 14y ago[deleted]
- codewright 14y agoThis is a pretty interesting post, but I'm seeing a common thread in most "experience reports" regarding making a webapp in Clojure. They're all built with with the presumption that the person doing the frontend work (HTML, CSS, JS) will also be doing the backend (Clojure, database) coding. This is almost never the case in my line of work. Hiccup violates this principle by embedding the html in my Clojure and Enlive couples markup with data tightly in ways that horrify me. The only approach I've seen that could work for more serious projects is using stencil because then the map of data you pass to the template-side is a 'contract' of sorts, but they can work with the data you pass however it works for them. That's somewhat regrettable as I prefer Jinja-style templating to mustache, but Stencil (mustache) is the only viable alternative I've found. I cannot possibly be the only person with a keen interest in Clojure who hasn't abandoned division of labor.
- kinleyd 14y agoI think most of the examples assume a single developer beginning the process of learning Clojure. That would explain what appears to be the assumption that one person will be handling both the front- and back-ends because it's easier to set up simple examples this way.
- asmala 14y agoBased on my experience, Hiccup is more productive than just about anything else if the frontend person is the backend person or otherwise comfortable with Clojure. The ability to easily and cleanly define and combine abstractions in the presentation layer has been big productivity boost for me as a solo developer. As a concrete example, a small hobby project I did resulted in a fairly comprehensive library of Bootstrap helpers with very little effort: * https://github.com/asmala/giddyup https://github.com/asmala/giddyup I don't have much experience with Enlive but I find the approach is intriguing. On paper it seems perfect for clean separation of markup and logic, but you're right that careless use of the library leads to tight coupling due to the selector naming. I wonder if it would be possible to circumvent this issue using custom HTML attributes or even pseudo-CFML custom tags to indicate logical units in HTML?
- 14y ago
- irahul 14y agoI have used Enlive and I still prefer traditional erb style templates. I actually use Slim(slim > haml) or Haml, but they are just syntactic sugar. Enlive, on one hand, allows designers to work on html which doesn't need any data binding, and then process the plain html. On the other hand, it's tightly coupled with the markup. A designer can't be sure that changing a class name or restructuring the markup won't break the templates. Rolling your own validations might be fun, or it isn't something I want to do when I am working on a project. I might have rolled out validations from last project which I can re-use, but I still prefer AR or WTForm validation over rolling my own(takes time, and if I am in a hurry, ends up not being generic enough to use in another project). Same goes for pagination. Need pagination? Here, # Add kaminari https://github.com/amatsuda/kaminari class UsersController def index @users = User.order(:name).page params[:page] end end # index.html.slim = paginate @users Done. Clojure is a pleasant, expressive and innovative language, but as the blog post pointed out, the ecosystem isn't vibrant enough yet.
- asmala 14y agoComing from Rails, I tend to agree that the Clojure ecosystem is still less mature, but not by as much as I initially thought. Missing Rails I18n, SimpleForm, or validations? Clojure has you covered: * https://github.com/ptaoussanis/tower https://github.com/ptaoussanis/tower * https://github.com/asmala/clj-simple-form https://github.com/asmala/clj-simple-form * http://clojurevalidations.info/ http://clojurevalidations.info/ Need more specialized libraries? Take a look at ClojureWerkz: * http://clojurewerkz.org/ http://clojurewerkz.org/ Having tried hard to understand the rather labyrinthine source of the original SimpleForm library, I was astonished by how easy Clojure made writing a similar library, clj-simple-form. The key contributing factors were Clojure's emphasis on simple data structures and powerful functions as opposed to classes, and the ability to pass around functions just like any other objects. For a lot of projects, I find ease of extensibility to be more important than ready libraries.
- kinleyd 14y agoClojure does make difficult things easy. And it's getting better and better with the rapid evolution of new libraries and middleware. Given one of the core differences in approach, composibility for Clojure and 'convention over configuration' for RoR - I don't think there will ever be a monolithic RoR equivalent in Clojure. Instead the micro-frameworks that are emerging are finding their niches, and are being designed from the ground up to work with other micro-frameworks. Working in tandem these compositions of micro-frameworks are quickly getting mature and I'm sure will be in the same league as RoR soon enough. What I like about this is it allows you to handle Clojure a micro-framework or middleware at a time. It's easier to digest this way, at least for me: Ring -> Compojure -> Hiccup - Enlive/Comb/Fleet [x] -> Korma -> Friend, followed by Domina, Enfocus and others on the ClojureScript side. [x]: marks where I am.
- deleted 14y ago[deleted]