integrant 2021-11-08

Hello, when I am using integrant, I have a config.edn listing down all the configuration details. May I know what is best practice when my routes in my ring-server needs to reference some of these details?

Maybe the part that would be helpful is knowing how to change more complicated ring routes into integrant components 🤔

Like if I have

(def config
  {:adapter/jetty {:port 8080, :handler (ig/ref :handler/all)}
   :handler/greet1 {:name "Alice"}
   :handler/greet2 {:name "Bobby"}})
(defmethod ig/init-key :adapter/jetty [_ {:keys [handler] :as opts}]
  (jetty/run-jetty handler (-> opts (dissoc :handler) (assoc :join? false))))

(defmethod ig/init-key :handler/greet1 [_ {:keys [name]}]
  (fn [_] (resp/response (str "Hello " name))))

(defmethod ig/init-key :handler/greet2 [_ {:keys [name]}]
  (fn [_] (resp/response (str "Hello " name))))
I don't really know how to do a :handler/all for this with compojure

You need use a router for :handler/all. e.g. reitit, compojure, ataraxy

So something along these lines:

(require '[reitit.core :as r])

(defmethod ig/init-key :my/router
  [_ {:keys [routes]}]
  (r/router
   routes))

(def config
  {:adapter/jetty {:port 8080, :handler (ig/ref :my/router)}
   :my/router {:routes
               [["/greet1" (ig/ref :handler/greet1)]
                ["/greet2" (ig/ref :handler/greet2)]]}
   :handler/greet1 {:name "Alice"}
   :handler/greet2 {:name "Bobby"}})

yeap supposing I use compojure. Typically it will be something like

(defroutes routes-handler
  (GET "/greet1" [] (greet1)
  (GET "/greet2" [] (greet2))
how might this be turned to integrant then 🤔

I'm not too familiar with compojure myself, but I assume it creates a var named routes-handler

So you could create an ig/init-key that returns that var

That might not work actually, since it's a macro and needs the handlers at compile time

Not sure if that's the same thing

Oh yeap just found that right before you replied but couldn't quite understand it since they left the compojure part out

Yeah doesn't seem to be very helpful 😅

Tho there's a sample project - https://github.com/the-frey/compojure-api-integrant/blob/master/src/compojure_api_integrant/handler.clj#L9 but I don't really understand where the api function (?) came from

I personally try to avoid macro based libs. But that's just me

Right - hmmm

I think the plan might be to move to reitit soon

but guess trying to avoid doing both that and refactoring of integrant stuff concurrently

but maybe that's the simpler way 🤔

You could first move to reitit, and then to integrant. If you want to do it in steps

You can also ask yourself if you really need to move at all 😄

oh for the integrant case - am already using it but currently the routes aren't being handled by integrant to handle the dependencies, so a hack-ish way to copy the integrant state was previously used - am trying to fix that currently haha

am not sure if im also slightly confused - because ^ is also to get integrant-repl is work correctly (and i read that integrrant and integrant-repl aren't exactly the same)

also I realise that in the guide compojure being used is https://github.com/metosin/compojure-api and am currently using https://github.com/weavejester/compojure

Ok so those are two different things

integrant-repl is an extension on integrant. Not sure what you mean by "they are not the same"

but think it is incomplete

Well it just makes developing your app with integrant easier

It's also something you generally only want in development

I guess for clearer context - in my project integrant-repl is already being used but running go doesn't setup the full system currently have run another function that copies integrant-repl.state/system into an atom. which the routes access using stuff like get-in to take values from

But anyway thanks for your help @kevin.van.rooijen ! 😄 Maybe I'll start with the refactoring to reitit

You're welcome! And good luck!

I’m on my phone but I did this by putting the compojure “app” into my integrant state, and then any time I changed a route I (halt!) and (go) to restart the app

When I’m on my computer I can show what I’ve done with actual code