How does your clojure backend stack look like?
Framework: Duct (+ataraxy routing)
DB: Postgres, exposed through Duct boundaries using HugSQL
Editor: Emacs + CIDER
Reloaded workflow: Integrant (part of Duct)
My conservative stack
- bidi for routing (but compojure will do as well)
- clojure.java.jdbc + Postgres
- start without a library like system, component, etc.; only introduce a library once you have a problem that it solves
Each choice has alternatives, but don’t worry that you’re missing out. Use what you feel comfortable with, it’s hard to go wrong. The only thing I’d worry about is overengineering, i.e. starting with too many clever tools. My approach: don’t anticipate growth pains; start from a clean slate (or a very basic scaffolding), and force yourself to wait for problems to actually manifest themselves before introducing the heavy machinery (core.async, component frameworks, clever reloading tools, logging frameworks, …).
Excellent advice thanks!
@pesterhazy’s approach, where the default is no libraries and no tooling until you need it, describes my philosophy as well.
Project Grizzly http server using java interop
single uberjar deployment.
- Faraday (DynamoDB)
- Emacs + CIDER
- http-kit (would like to use aleph at some point)
- bidi (server and client, sometimes even fetching routes from server for client)
- MongoDB via monger
- stuartsierra’s amazing component library
- struct for validation
- Single uberjar
- docker-compose setup with MongoDB, netdata and some other goodies (using the openjdk:8-slim image)
- IntelliJ (REPL integration is great!)
- Figwheel for client development
- Robo3T for database admin, or just shell (https://www.dbkoda.com/ looks promising)
HellHound ( Which uses Aleph, Pedestal Router, HellHound systems/components, re-frame)
HellHound system/components are similar to stuartsierra’s component but much simpler. Basically a system of components talking to each other using streams of data. Very similar to unix pipelines.
Kafka + Cassandra + Neo4j
FG42 ( My own Emacs )
- web: Pedestal + jetty
- reloaded workflow: integrant
- UI: Rum + citrus
- external: clj-http + core.async
- ring (for server)
- bidi (for routing clojure(script))
- component (awesome lib to manage state app clojure(script))
- korma with PostgreSQL (for manage postgres query)
- clojure.spec (just awesome, validation for clojure(script))
- clojure.test (for testing)
- specter (for parse complex data structure)
- Rum (for UI and server templating)
- Garden (for CSS)
reloaded.repl (developer convenience)
We use component for all our applications and couple off the shelf components (Jetty, hikari-cp, nrepl, Carmine).
On top of that we developed our own libraries/components to handle:
- RabbitMQ consumers/producers
- submitting StatsD metrics and monitoring
- recurring scheduled jobs
(I’m probably forgetting couple of others)
I’m hoping that we will be able to open source them soon as we couldn’t find anything that would fit the component model.
While I sometimes miss robust frameworks like Rails I found it way easier to build new services in Clojure as most of libraries can be nicely tied together - the amount of glue code comparing to other languages is minimal.