Search code examples
clojureleiningenhttp-kit

Clojure reloaded workflow without using library like Component?


So I have a simple webapp that has a main method that starts an http server. The dev setup that I want to achieve is basically something like using lein auto, but I want to stop and start my server and reload namespaces automatically on file change. This seems like something that should be straightforward and easy, but so far I haven't found any lein plugins or other ways to really achieve this.


Solution

  • I think what you're looking for is what I was looking for, a combination of tools.namespace and wrap-reload.

    Here's what I came up with:

    (ns your-project.core
      (:require [clojure.tools.namespace.repl :as tn]
                [org.httpkit.server :as http]
                [ring.middleware.reload :refer [wrap-reload]]
                [compojure.core :refer [defroutes GET]]
    
    (defroutes create-app []
      (GET "/" [] (fn [req] "hello world")
    
    (defonce server (atom nil))
    
    (defn start []
      (let [app (create-app)]
        (reset! server (http/run-server (wrap-reload app) {:port 3000}))
        (println (str "Listening on port " 3000))))
    
    (defn stop []
      (when @server
        (@server :timeout 100)
        (reset! server nil)))
    
    (defn restart []
      (stop)
      (tn/refresh :after 'your-project.core/start))