Clojure Duct setup with MongoDB, Foundation, and Buddy
Setup a new duct site
Why Duct? Well it's a great starting point using most of what I want. Compojure, Ring, Component, ClojureScript, 12 Factor methodology.
lein new duct nspkt.ui +cljs +example +heroku +site cd nspkt.ui && lein setup
Ok, we need some other stuff, like MongoDB, a css framework (Foundation), and authentication.
MongoDB Setup
I like Monger, so let's add that. In project.clj, add the dependency.
[com.novemberain/monger "3.0.2"]
We need to add a connection string to the env for monger. This took a minute to figure out.
In the project.clj file, under :profiles
> :project/dev
> :env
, add :url
.
This will write the values to .lein-env.
{:port "3000", :url "mongodb://localhost:27017/nspkt"}
Then we need to update the config.clj to grap the value. Like so.
(def environ
{
:http {:port (some-> env :port Integer.)}
:db {:url (some-> env :url)}
})
And add a compontent for System.
(ns nspkt.ui.component.mongodb
(:require [com.stuartsierra.component :as component]
[monger.core :as mg]
)
)
(defrecord MongoDb [url]
component/Lifecycle
(start [this]
(let [{:keys [conn db]} (mg/connect-via-uri (:url this))]
(assoc this :conn conn :db db)
)
)
(stop [this]
(if-let [conn (:conn this)]
(do
(mg/disconnect conn)
(dissoc this :conn :db)
)
this
)
)
)
(defn db-component [options]
(map->MongoDb options)
)
Next add the component to the system, add have the example endpoint depend on it.
Don't forget to add to the :requires
. In system.clj.
...
(-> (component/system-map
:app (handler-component (:app config))
:http (jetty-server (:http config))
:db (db-component (:db config))
:example (endpoint-component example-endpoint))
(component/system-using
{:http [:app]
:app [:example]
:example [:db]}))
...
And using the component in the example endpoint, endpoint/example.clj.
(ns nspkt.ui.endpoint.example
(:require [compojure.core :refer :all]
[monger.collection :as mc]
[clojure.java.io :as io]))
(defn example-endpoint [{:keys [db] :as config}]
(context "/example" []
(GET "/" []
(prn-str
(mc/find-maps (-> db :db) "reports")
)
)))
Great! Let's make sure everything is working. We need to lein deps
and start the
REPL again.
If you run into trouble it's some times easier to see what's going by lein run
ing.
I added a test record in MongoDB just to see everything works.
It's not pretty, but it's pulling stuff out of the DB! Now let's add a CSS framework to help thing look a little better.
Webmentions
These are webmentions via the IndieWeb and webmention.io. Mention this post from your site: