I've struggled with the same issue as you, Sven.  In a web app, your 
handlers wind up needing access to every other component in the system 
because they are the first point of contact with the outside world.

In my apps, I've done this one of two ways:

1. Close over the needed dependencies when creating the ring handlers. 
 (Instead of just associating it into the request map.)  For example:

(defn make-handler [db sched]
   (routes
      (GET "/" request ...code which uses the db....)
      (POST "/" request ...code which uses the scheduler...)))

2. Make the system a global variable in your handler namespace.  For 
example:

(def system (atom nil))

(defroutes all-the-routes
   (GET "/" request ...do something with (:db @system)...))

As long as you don't let code further down the chain rely on having a 
:system key in the request map or a system global variable, you're still 
achieving pretty good separation of concerns.

Brendan

On Friday, August 8, 2014 7:16:49 AM UTC-4, Sven Richter wrote:
>
> Hi,
>
> I am trying to integrate Stuarts component library into my application. I 
> am not sure if I use it correctly or do something else wrong or just have a 
> wrong mindset. So I will explain how I am currently using it and the 
> problem I see with it.
>
> I have three components: database, a scheduler and web application (note 
> that my example is simplified to get faster to the point). These components 
> are built like this:
>
> (component/system-map
>       :database (db db-uri)
>       :scheduler (component/using (scheduler) [:database])
>       :web-app (component/using (web-app)
>                                 [:database
>                                  :scheduler] ))
>
> And in my web-app I do something like this:
>
> (start [component]
>     (let [db-conn (get-in web-app [:database :db-conn])]
>       (assoc component :server
>                        (run-server (make-handler web-app db-conn) {:port 
> port}))))
>
> And make-handler is a middleware that associates the database component 
> into the request map.
>
> Now as I added the scheduler to my system it occured to me that I will 
> have to associate the scheduler into the request map too to access it and I 
> might have to do that for every other component that is coming along the 
> road.
> So basically I am tying my web-app to to all these components and I am 
> tying some components to other components (like scheduler component to the 
> database component).
>
> And by tying this things together this way they do depend on each other 
> and I cannot move them anymore. This came to my mind as I started thinking 
> about microservices.
>
> So let's say I want to convert the scheduler into a restful microservice, 
> it's hard to pass in a database connection into it via HTTP, so it seems 
> like it's not decoupled enough. Does that make sense?
>
> Am I using it wrong? Is it ok to pass all kind of dependencies into the 
> request map and shove it around in the web application? Any other 
> suggestions / remarks?
>
> Best Regards,
> Sven
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to