I'm writing a toy application to learn about Compojure, and using it for database-backed web-applications.
I know, I could create a uberjar that automatically launches the server on login, if I compile with lein ring uberjar
. Now I want to experiment with a multifunctional .jar file, the idea is that upon launching the jar I can decide if I want to do database administration or start the server.
In my core.clj I have defined some routes via defroutes
and provided that in the project.clj under :ring {:handler ...}
.
My question now is: how can I just start the ring server from a function, with as few dependencies and code as possible?
This issue has examples on starting the server from the -main
function, but uses a pleothora of dependencies I can't resolve, some occult functions without explanations, and is almost sure to be outdated for two years.
I can't find any hints in the Compojure documentation and wiki, pointers to docs/tuts are welcome, too.
Edit: A working version, from schaueho's answer and the ring tutorial:
(ns playground.core
(:require [ring.adapter.jetty :refer :all]
[compojure.core :refer :all]
[compojure.route :as route]))
(defroutes app-routes
(GET "/" [query]
(do (println "Server query:" query)
"<p>Hello from compojure and ring</p>"))
(route/resources "/")
(route/not-found "<h1>404 - Page not found</h1>"))
(run-jetty app-routes {:port 8080 :join? false})
For some reason, calling run-jetty
would give me ClassNotFoundExceptions with the exact same code before I restarted the REPL. I guess a polluted namespace had prevented it from working.
Take a look at the Getting started section of the ring documentation for an example which uses Jetty (just like lein ring
does).
You can drop the call to run-jetty
inside the -main
function. Compojure routes function as handlers, so you can drop them as an argument to the call to run-jetty
(as in (jetty/run-jetty main-routes port)
.