Search code examples
web-applicationsclojurecompojurering

Compojure - how to start server from a function?


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.


Solution

  • 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).