2013-11-04 7 views
13

कैसे रिंग हैंडलरों में सबसे अधिक आसानी से राज्य को इंजेक्ट करता है (वैश्विक वर्रों का उपयोग किए बिना)?एक अंगूठी हैंडलर के लिए पैरामीटर के रूप में राज्य पास?

(defroutes main-routes 
    (GET "/api/fu" [] (rest-of-the-app the-state))) 

(def app 
    (-> (handler/api main-routes))) 

मैं main-routes के लिए compojure हैंडलर में the-state प्राप्त करना चाहते हैं:

यहाँ एक उदाहरण है। के विभिन्न घटकों को

(defn create-app-state [] 
    {:db (connect-to-db) 
    :log (create-log)}) 

एक गैर अंगूठी आवेदन मैं एक मुख्य कार्य में राज्य बना सकते हैं और यह इंजेक्शन लगाने शुरू होगा, या यह के कुछ हिस्सों में समारोह पैरामीटर के रूप में: राज्य के साथ बनाए गए नक्शे की तरह कुछ हो सकता है आवेदन पत्र।

क्या वैश्विक वैरिएबल का उपयोग किए बिना अंगूठी के :init फ़ंक्शन के साथ ऐसा कुछ किया जा सकता है?

+0

क्या आप प्रति सत्र राज्य या वैश्विक स्थिति की तलाश में हैं? – astine

+0

वैश्विक - समान जीवनकाल: init और: – 4ZM

उत्तर

20

मैंने इसे कुछ तरीकों से देखा है। पहला मिडलवेयर का उपयोग कर रहा है जो अनुरोध मानचित्र में राज्य को एक नई कुंजी के रूप में इंजेक्ट करता है। उदाहरण के लिए:

(defroutes main-routes 
    (GET "/api/fu" [:as request] 
    (rest-of-the-app (:app-state request)))) 

(defn app-middleware [f state] 
    (fn [request] 
    (f (assoc request :app-state state)))) 

(def app 
    (-> main-routes 
     (app-middleware (create-app-state)) 
     handler/api)) 

अन्य दृष्टिकोण defroutes करने के लिए कॉल, जो पर्दे के पीछे कोई हैंडलर बना सकते हैं और, एक वर के लिए असाइन करें एक समारोह है कि कुछ राज्य को स्वीकार करेंगे और उसके बाद रूट बनाने के साथ होगा बदलने के लिए है, पैरामीटर के रूप में राज्य इंजेक्शन लगाने के मार्ग परिभाषाओं में कॉल कार्य करने के लिए:

(defn app-routes [the-state] 
    (compojure.core/routes 
    (GET "/api/fu" [] (rest-of-the-app the-state)))) 

(def app 
    (-> (create-app-state) 
     app-routes 
     api/handler)) 

एक विकल्प को देखते हुए, मैं शायद दूसरा दृष्टिकोण के साथ जाना चाहते हैं।

+1

को नष्ट करें धन्यवाद! दूसरा दृष्टिकोण एक अच्छा फिट लगता है। पहला एक थोड़ा हैक-आश महसूस करता है। – 4ZM

-1

ऐसा करने के लिए "सही" तरीका एक गतिशील रूप से बाध्य var का उपयोग करना है। आप के साथ एक वर को परिभाषित:

(def ^:dynamic some-state nil) 

और फिर आप कुछ अंगूठी मिडलवेयर जो प्रत्येक हैंडलर कॉल के लिए वर बांधता बनाएँ:

(defn wrap-some-state-middleware [handler some-state-value] 
    (fn [request] 
    (bind [some-state some-state-value] 
     (handler request)))) 

आप अपने 'मुख्य में इस का उपयोग कर इस का प्रयोग करेंगे निर्भरता सुई 'फ़ंक्शन जहां आप सर्वर लॉन्च करते हैं:

(def app (-> handler 
      (wrap-some-state-middleware {:db ... :log ...}))) 
+0

आप गतिशील का उपयोग कर बहुत सारे राज्य प्रबंधन में जा रहे हैं। इससे बाद में कुछ गंभीर समस्याएं हो सकती हैं। – Virmundi

संबंधित मुद्दे