2017-12-02 167 views
0

我的網絡客戶端(寫在cljs)連接到後端(編寫在clj)需要進行一些第三方API調用。它必須在服務器上完成,然後結果應該以特定方式進行轉換併發送回客戶端。如何在clojure/ring中發起http呼叫?

這裏是我的網址

(defn get-orders [req] 
    (let [{:keys [sig uri]} (api-signature :get-orders)] 
    (client/get uri 
       {:async? true} 
       (fn [response] {:body "something"}) 
       (fn [exception] {:body "error"})))) 

,而不是返回{:body "something"}的一個處理程序,它返回以下錯誤:

No implementation of method: :render of protocol: #'compojure.response/Renderable found for class: org.apache.http.impl.nio.client.FutureWrapper 

我在做什麼錯?

+0

如果FutureWrapper是一個Java未來,然後嘗試使用deref或@來解析它。 –

回答

2

當您指定{:async? true}時,clj-http.client/get將返回a future這是您得到的錯誤消息中的FutureWrapper

所以,如果你不需要異步,不要使用它。這是一個同步環處理程序的例子,它調用第三方url並返回返回的響應。

(defn handler [request] 
    (response {:result (client/get "http://example.com")})) 

如果您確實需要異步,請使用異步版本的環處理程序。

(defn handler [request respond raise] 
    (client/get "http://example.com" 
       {:async? true} 
       (fn [response] (respond {:body "something"})) 
       (fn [exception] (raise {:body "error"})))) 

不要忘記配置web服務器適配器以使用異步處理程序。例如,對於碼頭,設置:async?標誌true像這樣

(jetty/run-jetty app {:port 4000 :async? true :join? false}) 

如果要同時調用多個第三方URL和一次web客戶端返回,使用promise幫助

(defn handler [request] 
    (let [result1 (promise) 
     result2 (promise)] 
    (client/get "http://example.com/" 
       {:async? true} 
       (fn [response] (deliver result1 {:success true :body "something"})) 
       (fn [exception] (deliver result1 {:success false :body "error"}))) 
    (client/get "http://example.com/" 
       {:async? true} 
       (fn [response] (deliver result2 {:success true :body "something"})) 
       (fn [exception] (deliver result2 {:success false :body "error"}))) 
    (cond 
     (and (:success @result1) 
      (:success @result2)) 
     (response {:result1 (:body @result1) 
       :result2 (:body @result2)}) 

     (not (:success @result1)) 
     (throw (ex-info "fail1" (:body @result1))) 

     (not (:success @result2)) 
     (throw (ex-info "fail2" (:body @result2)))))) 
+0

謝謝你這樣詳細的答案! – Bravi