Overview of Clojure Web Servicesλ︎
A Web service receives data, does something with that data and returns data as a result. This is the essence of how a function works in Clojure. So its really simple to design web apps with Clojure.
Clojure data is managed via immutable data structures. The majority of the Clojure code will be stateless or managing state with immutable data structures, therefore code for services will be less complex and less prone to conflicts.
Relevant changes to data is persisted to a data store, e.g. PostgreSQL, Datomic or XTDB
So reliable services are very easy to build and simple to scale via parallelism.
Libraries over frameworksλ︎
Clojure takes a modular approach to building services, assembling commonly used libraries from the community.
Java Interoperability is simple in Clojure, so its trivial to use Java libraries or any libraries that run on the JVM (Scala, Jython, etc.).
Web services in Clojure are typically built from a collection of highly focused libraries. Each library has a specific focus and enables a modular approach, as you can swap components & libraries easily should there be value in a different approach.
Common libraries for web app development include:
- Ring - a web application library
- Compojure - an simple way to define routes for your ring webapp
- Hiccup or Selmer- to generate HTML from Clojure data structures
- Pedestal
- jdbc.next - a modern low-level Clojure wrapper for JDBC access to databases
- clojure.java.jdbc - simple low level SQL library
- Korma, YesQL, hugSql - database abstraction layers
- Prismatic Schema - database schema mapping
- Migratus - database migrations (and all the things)
Large frameworks constrain the design of a service, forcing development to live inside the constraints of that framework as it can be difficult to break out of the design the framework imposes.
Project templatesλ︎
Projects can be created from templates to avoid starting from scratch each time.
deps-new creates Clojure CLI projects from templates and is very simple to create your own templates
clj-new supports a very wide range of templates although has a more involved design when it comes to creating your own templates. Maintained templates used by clj-new should support both Clojure CLI and Leiningen
Convert Leiningen project to Clojure CLI
Add a deps.edn
file that contains a {}
hash-map with a :deps
key that is associated with a hash-map of library dependencies, the same dependencies from the project.clj configuration file updated to the Clojure CLI format, e.g. {org.clojure/clojure {:mvn/version "1.11.3"}}
There are many great templates to try that provide insight into building webapps in Clojure.
- compojure - a common web application approach with ring and compojure
- compojure-api - quickly build API's with ring, compojure and openapi (swagger) for self-documentation
- luminus - a flexible template to create server-side and full stack web applications
- pedestal-service - an opinionated, extensible & scalable framework
- duct - data-oriented production-grade server-side web applications
- JUXT Edge - a curated base project to build your own applications and services
You can find a range of project templates by searching for lein-template on Clojars.org. There is also a guide to writing templates on Leiningen.org