Skip to content

Instantly share code, notes, and snippets.

@benzap
Created April 2, 2018 10:57
Show Gist options
  • Select an option

  • Save benzap/ae0c48290f216f92e48f3d6f60fc00ca to your computer and use it in GitHub Desktop.

Select an option

Save benzap/ae0c48290f216f92e48f3d6f60fc00ca to your computer and use it in GitHub Desktop.
Middleware Implementation using less side-effects and mutable values
(ns middleware)
(def default-response
{:status :init
:done false
:value nil})
(def default-request
{})
(defn run-middleware
"Threads the request & response maps through each `mid-fn` stored in the vector `middlewares`
Return Value:
A vector containing [request response]"
([middlewares request response]
(reduce (fn [result mid-fn] (if-not (-> result second :done) (mid-fn result) result))
[request response] middlewares))
([middlewares request] (run-middleware middlewares request default-response))
([middlewares] (run-middleware middlewares default-request default-response)))
(defn middleware-init
[[request response]]
(println "Middleware init")
(Thread/sleep 1000)
[request (assoc response :status :init)])
#_(run-middleware [middleware-init])
(defn middleware-init-value
[[request response]]
[request (assoc response :value 0)])
#_(run-middleware [middleware-init
middleware-init-value])
(defn middleware-increment-value
[[request response]]
[request (update response :value inc)])
#_(run-middleware [middleware-init
middleware-init-value
middleware-increment-value])
;; Not very idiomatic, you're introducing a side-effect
;;
;; What is this function doing?
;; - incrementing value
;; - displaying value
;; - decrementing value
;; - displaying value
#_(defn update-3
[req res next]
(swap! res update :value inc)
(println (str "Current response value is: " @res ". Calling next."))
(next)
(println (str "Value near end is: " @res))
(swap! res update :value dec))
(defn middleware-decrement-value
[[request response]]
[request (update response :value dec)])
(defn middleware-display-value
[[request response]]
(println "Current Response Value is: " (:value response))
[request response])
#_(run-middleware [middleware-init
middleware-init-value
middleware-increment-value
middleware-increment-value
middleware-display-value
middleware-decrement-value
middleware-display-value])
(defn wrap-init-value
"Wrap middleware to initialize value to `value`
Note: This resembles how ring handler middleware is implemented wrt- request map"
[value]
(fn [[request response]]
(println "Reset Value to: " value)
[request (assoc response :value value)]))
#_(run-middleware [middleware-init
middleware-init-value
middleware-increment-value
middleware-increment-value
middleware-display-value
middleware-decrement-value
middleware-display-value
(wrap-init-value 1)])
(defn middleware-done
"Final middleware to stop the chain."
[[request response]]
[request (assoc response :done true)])
(defn middleware-critical
"Middleware that should never run"
[[request response]]
(println "Running middleware 6")
(throw (Exception. "Eeek I was not supposed to run!")))
(defn -main
[]
(println "Running middleware")
(println
(run-middleware [middleware-init
middleware-init-value
middleware-increment-value
middleware-increment-value
middleware-display-value
middleware-decrement-value
middleware-display-value
(wrap-init-value 1)
middleware-done
middleware-critical])))
(-main)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment