0
votes

I'm new to Clojure, and trying to get a few simple web routes set up. I want the routes to reload all associated code in development, but not in production.

I was only able to get this to work using the var's for the routes, not the actual symbols. Can someone explain if I'm doing this wrong? If not, why is the var required?

(def app-handler
  (let [formats [:json-kw :edn :yaml-kw :yaml-in-html :transit-json :transit-msgpack]
        wrapped-api (wrap-restful-format #'routes/api-routes :formats formats)
        combined-routes (compojure.core/routes wrapped-api #'routes/html-routes)
        with-defaults (wrap-defaults combined-routes api-defaults)]
    (if (is-dev?)
      ; Development
      (wrap-reload with-defaults)
      ; Production
      with-defaults)))

(Note #'routes/api-routes and #'routes/html-routes above).

1
This is because app-handler closes over your route functions, and if you don't use the var, there is no way for the server instance that is provided your app-handler as an argument to see the updates. See this answer for a more complete description and demonstration.noisesmith
@noisesmith Thanks for the quick reply! The other answer is quite good, I just didn't know what to search for. Would using the var have any kind of meaningful performance impact vs. some other method using a de-referenced value?Brandon
A var is considered the standard way to do this (at least during dev).noisesmith
If you want to answer I will accept :)Brandon

1 Answers

1
votes

In a manner described in more detail in another answer, the server ends up capturing your route functions when they are passed in, and if you provide the var, this will ensure that the server uses any updated definitions.

This is considered the normal way to provide your route or handler function during development, so that you can see updated definitions without having to restart your web server process.