For websites, which is not what all HTTP servers are, your primary task is often to produce HTML responses.
hiccup
to your deps.ednThis is a library which takes data structures and produces HTML.
The upside to using something like this to produce HTML is that you can have your HTML embedded directly into the code without a separate templating language.
The downside is that your HTML won't be already in HTML form, which precludes usage of some tooling and people.
{:paths ["src"]
:deps {org.clojure/clojure {:mvn/version "1.12.0"}
ring/ring {:mvn/version "1.13.0"}
metosin/reitit-ring {:mvn/version "0.7.2"}
org.clojure/tools.logging {:mvn/version "1.3.0"}
org.slf4j/slf4j-simple {:mvn/version "2.0.16"}
hiccup/hiccup {:mvn/version "2.0.0-RC3"}}
:aliases {:nREPL
{:extra-paths ["dev"]
:extra-deps
{nrepl/nrepl {:mvn/version "1.3.0"}}}
:dev {:extra-paths ["dev"]}}}
It's important to only use the hiccup2.core
namespace. The hiccup.core
one has some intrinsic problems you don't want to deal with.
Similarly to reitit
routes, the input here is a data structure. There are tools for converting HTML
snippets you want to use automatically into this hiccup format. Some are documented HERE.
(ns example.routes
(:require [reitit.ring :as reitit-ring]
[clojure.tools.logging :as log]
[hiccup2.core :as hiccup]))
(defn hello-handler
[system request]
{:status 200
:headers {"Content-Type" "text/html"}
:body (str
(hiccup/html
[:html
[:body
[:h1 "Hello, world"]]]))})
(defn goodbye-handler
[system request]
{:status 200
:headers {"Content-Type" "text/html"}
:body (str
(hiccup/html
[:html
[:body
[:h1 "Goodbye, world"]]]))})
(defn routes
[system]
[["/" {:get {:handler (partial #'hello-handler system)}}]
["/goodbye" {:get {:handler (partial #'goodbye-handler system)}}]])
(defn not-found-handler
[_request]
{:status 404
:headers {"Content-Type" "text/html"}
:body (str
(hiccup/html
[:html
[:body
[:h1 "Not Found"]]]))})
(defn root-handler
[system request]
(log/info (str (:request-method request) " - " (:uri request)))
(let [handler (reitit-ring/ring-handler
(reitit-ring/router
(routes system))
#'not-found-handler)]
(handler request)))