2014-08-29 58 views
2

当定义组合处理程序例如通过使用defroutes宏,我可以做这样的事情:如何获得组合处理程序中的自链接?

(defroutes home-routes 
    (GET "/myhome/:id" [ id ] (home-page))) 

(defn home-page [ id ] 
    (... do something ...)) 

所以我知道如何通过一块path参数。但想象一下,我想用自链接返回一个HAL + JSON对象。我如何获得defroutes将整个URI传递给home-page函数?

回答

3

戒指请求地图包含构建“自我链接”的所有必要信息。具体而言,可将:scheme,:server-name,:server-port:uri值组装成完整的请求URL。当我遇到这个问题时,我创建了Ring中间件,将组装好的请求URL添加到Ring请求映射中。只要我将请求映射(或其某个子集)传递到处理程序,我就可以在处理程序中使用请求URL。下面的代码片段显示了实现此的一种方式:

(defroutes app-routes 
    (GET "/myhome/:id" [id :as {:keys [self-link]}] (home-page id self-link)) 
    (route/resources "/") 
    (route/not-found "Not Found")) 

(defn wrap-request-add-self-link [handler] 
    (fn add-self-link [{:keys [scheme server-name server-port uri] :as r}] 
    (let [link (str (name scheme) "://" server-name ":" server-port uri)] 
     (handler (assoc r :self-link link))))) 

(def app 
    (-> app-routes 
    handler/site 
    wrap-request-add-self-link)) 
+1

我记得和反向代理请求麻烦,即你有你的戒指服务器localhost':1234',但公共交通到达'domain.net:80' 。在这种情况下,至少':server-port'应该是1234。 (另外,如果协议不同,它不会变得更容易; IIRC你必须看看['X-Forwarded-For'](http://en.wikipedia.org/wiki/X-Forwarded-For)在那些情况下。) – xsc 2014-08-29 19:41:44

+1

我正在使用Jetty,它提供了对“X-Forwarded-For”的支持(如果配置为这样做)。因此,Ring请求映射包含“公共”方案,服务器名称和服务器端口。因此,即使使用反向代理,答案中的代码也可以正常工作。 – ez121sl 2014-08-29 20:03:53