Search code examples
mongodbclojureringluminus

Clojure luminus framework how to call mongodb connect with mount


I started to develop using Clojure luminus framework with mongodb (with monger library). It was very hard to understand how to implement mount library to start the db connection.

I figured out that code should put handler.clj 's init function.

But I cannot figure out how to tell mount to start the database connection.

Please could you give me a hand?

Here gores my development config.clj

    (ns vippro.config
  (:require [selmer.parser :as parser]
            [clojure.tools.logging :as log]
            [vippro.dev-middleware :refer [wrap-dev]]
))

(def defaults
  {:init
   (fn []
     (parser/cache-off!)
     (log/info "\n-=[vippro started successfully using the development profile]=-"))
   :middleware wrap-dev})

and in handler.clj 's init function

(defn init
  "init will be called once when
   app is deployed as a servlet on
   an app server such as Tomcat
   put any initialization code here"
  []
  (when-let [config (:log-config env)]
    (org.apache.log4j.PropertyConfigurator/configure config))
  (doseq [component (:started (mount/start))]
    (log/info component "started"))
  ((:init defaults)))

my main problem is how should I call this function from init proper way

(defn connect! []
  ;; Tries to get the Mongo URI from the environment variable
  (reset! db (-> (:database-url env) mg/connect-via-uri :db)))

Solution

  • Your original question was about how to use mount to do this.

    It doesn't look like that's what you are doing, although your mongodb client is initializing, I suspect it is doing it when the namespace loads.

    You defined a connect! function which connects and puts the value in an atom db. This is not the proper way to manage state with mount since you are using your own atom to store the state. Instead, try using mount.core/defstate to create and destroy the mongo client:

    (defstate settings
      :start {:mongo-uri "mongodb://localhost/my-database"})
    
    (defn- mongo-connect
      [{:keys [mongo-uri]}]
      (mg/connect-via-uri mongo-uri))
    
    (defn- mongo-disconnect
      [{:keys [conn] :as mongo-client}]
      (mg/disconnect conn))
    
    (defstate mongo-client
      :start (mongo-connect settings)
      :stop (mongo-disconnect mongo-client))
    
    (defn db [] (:db mongo-client))
    

    By doing this you get the benefits of mount.

    Then you could use environ/env as your settings and export MONGO_URI="mongodb://..."