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

Running Rings Around Rack

Avatar for Alex Wheeler Alex Wheeler
November 16, 2017
84

Running Rings Around Rack

Clojure NYC

Avatar for Alex Wheeler

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)))))