Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Running Rings Around Rack

Alex Wheeler
November 16, 2017
70

Running Rings Around Rack

Clojure NYC

Alex Wheeler

November 16, 2017
Tweet

Transcript

  1. • “It is better to have 100 functions operate on

    one data structure than to have 10 functions operate on 10 data structures” - Alan Jay Perlis
  2. • “It is better to have 100 functions operate on

    one data abstraction than 10 functions on 10 data structures.” - Rich Hickey
  3. (conj [1 2] 3) => [1 2 3] (conj '(1

    2) 3) => '(3 1 2) (conj #{1 2} 3) => #{1 3 2} (conj {1 2} {3 4}) => {1 2, 3 4}
  4. (assoc {} :name "Alex" :city "NYC") => {:name "Alex" :city

    "NYC"} (assoc [1 2] 2 3) => [1 2 3] (assoc nil :name "Alex") => {:name "Alex"}
  5. (def company {:employee-count 24}) (def employees-per-company [1 20 500]) (update

    company :employee-count inc) => {:employee-counts 25} (update employees-per-company 0 inc) => [2 20 500] (:employee-count company) => 24 (first employees-per-company) => 1
  6. (defn handler [request] {:status 200 :headers {"Content-Type" "text/json"} :body ""})

    (run-jetty handler {:port 3000}) class App def call(env) ['200', {'Content-Type' => 'application/json'}, []] end end Rack::Handler::WEBrick.run App.new
  7. (defn handler [req] { :status 200 :headers {} :body ""

    }) (defn timestamp [handler] (fn [request] (handler (assoc request :time (java.util.Date.))))) (def app (timestamp handler)) (run-jetty app {:port 3000})
  8. (defn handler [req] { :status 200 :headers {} :body ""

    }) (defn remove-sensitive-data [handler] (fn [request] (handler (dissoc request :bank-number)))) (defn timestamp [handler] (fn [request] (handler (assoc request :time (java.util.Date.))))) (def app (remove-sensitive-data (timestamp handler)))
  9. (def sensitive-data [:foo]) (apply dissoc {:foo "2342345"} sensitive-data) => {}

    SENSITIVE_DATA = [:foo] {foo: 'bar'}.delete_if {|k, v| SENSITIVE_DATA.include?(k)} => {}
  10. class RemoveSensitiveData SENSITIVE_DATA = [‘bank-account-num’, ‘social-security’] def initialize(app) @app =

    app end def call(env) req = Rack::Request.new(env) req['params'].delete_if { |k, v| SENSITIVE_DATA.include?(k) } @app.call(env) end end
  11. def call(env) req = Rack::Request.new(env) req['params'].delete_if { |k, v| BAD_WORDS.include?(v)

    } Analytics.update(req) Logging.log(req) Database.update(req) @app.call(env) end
  12. (defn remove-bad-words [handler] (fn [request] (analytics/update request) (logging/log request) (database/update

    request) (handler (update-in request [:params] #(apply dissoc % bad-words)))))