2015-11-01 61 views
0

在斯圖爾特Sierra的組件的README功能,還有一個功能add-user被給出作爲一個例子,但沒有看到其他地方:的Clojure - 通組件啓動過程中不執行或停止

(defn add-user [database username favorite-color] 
    (execute-insert (:connection database) 
    "INSERT INTO users (username, favorite_color)" 
    username favorite-color)) 

我想象它可以在Web服務器路由上執行(例如)。我毫不費力地想象,usernamefavorite-colour將是該路線的參數,因此在致電add-user時可隨時獲得。

我想這會使web-server(例如)組件的database組件。 但是,我在計算組件實例參數add-user應該來自哪裏時遇到了一些問題。

我覺得直接訪問system(即做(:database my-system-ns/system)))來檢索它會首先破壞部分使用組件的目的。

舉例來說,如果我使用的基座上,我可以有我的基架部件(誰有權訪問數據庫組件)的設置此項:

::bootstrap/routes #(deref #'my-routes-ns/routes) 

,這將是類似的東西:

;; in my-routes-ns 
(defroutes routes [[[ "/add-user" {:post add-user-handler} ]]]) 

;; same function again for clarity 
(defn add-user [database username favorite-color] 
    (execute-insert (:connection database) 
    "INSERT INTO users (username, favorite_color)" 
    username favorite-color)) 

;; my route handler 
(defn add-user-handler [request] 
    ;; How do I get access to the database component from here ? 
    (add-user database "user" "red")) 

如何在本例中訪問我的database組件?

回答

1

僅供參考,the README of component建議在一個或多個組件中創建一個封閉,

(defn app-routes 
    "Returns the web handler function as a closure over the 
    application component." 
    [app-component] 
    ;; Instead of static 'defroutes': 
    (web-framework/routes 
    (GET "/" request (home-page app-component request)) 
    (POST "/foo" request (foo-page app-component request)) 
    (not-found "Not Found"))) 

(defrecord WebServer [http-server app-component] 
    component/Lifecycle 
    (start [this] 
    (assoc this :http-server 
      (web-framework/start-http-server 
      (app-routes app-component)))) 
    (stop [this] 
    (stop-http-server http-server) 
    this)) 

(defn web-server 
    "Returns a new instance of the web server component which 
    creates its handler dynamically." 
    [] 
    (component/using (map->WebServer {}) 
        [:app-component])) 
2

在典型應用中,你可能有一個web-server組件(見component/using)取決於你database組件,並與database組件,它的消費者可以打電話查詢數據庫相關聯的公共功能的集合。

web-server組件將負責設置您的請求處理程序並啓動一個偵聽器(如Jetty)。這將涉及採取database組件並將其注入到您的處理程序中,可能通過部分應用程序(如果您的處理程序看起來像(defn handler [database request] …)那樣),以便它可以在實際database組件上調用add-user

請注意,根據您的應用程序的設計,您的設置可能與上述內容完全不符 - 例如,web-server只能通過一層或多層中間組件使用database組件。

+0

我的想法,但我不確定如何在實踐中應用它,因爲我不認爲我可以通過它以'defroutes'爲例。 – nha

+0

啊顯然,預期的用途是將它放入中間件/攔截器的請求中。我必須嘗試:https://groups.google.com/forum/#!topic/clojure/12-j2DeSLEI/discussion – nha

+0

是的,這當然是一種可能性。在[Rook](https://github.com/AvisoNovate/rook)中,您可以使用參數解析器來實現此目的。回到Pedestal,你也可以使用'expand-routes'而不是'defroutes';這將允許您在'web-server'啓動過程中使用任何必需的組件建立路由定義。 –