ring

  • handler fn: req -> resp
  • middleware fn: handler -> handler
    • request middleware
      (defn wrap-user [handler user-info]
      (fn [request]
        (handler
          (assoc request :user user-info))))
      
    • response middleware
      (defn wrap-content-type [handler content-type]
      (fn [request]
        (let [response (handler request)]
          (assoc-in response [:headers "Content-Type"] content-type))))
      
    • req+resp middleware
      (defn wrap-cookies [handler options]
      (fn [request]
        (-> request
            (cookies-request options)
            handler
            (cookies-response options))))
      
  • middleware order: bottom up
    ; let said we have 2 middleware
    (defn wrap-1 [handler]
      (fn [req]
        (handler
          (assoc req :a 1))))
    
    (defn wrap-2 [handler]
      (fn [req]
        (handler
          (assoc req :a 2))))
    
    ; when use it, order will be apply for wrap-2 first, then wrap-1
    ; it seem confuse at first, as it's reverse with -> order
    (-> handler
        wrap-1
        wrap-2)
    
    ; let see why
    (wrap-2 (wrap-1 handler))
    
    (wrap-2 #(handler (assoc % :a 1)))
    
    (fn [req]
      (#(handler (assoc % :a 1))
        (assoc req :a 2)))
    
    (fn [req]
      (handler (assoc (assoc req :a 2) :a 1)))
    
    ; so after all, fn from wrap-2 is apply to req first, then wrap-1