-
Notifications
You must be signed in to change notification settings - Fork 0
/
core.clj
49 lines (40 loc) · 1.74 KB
/
core.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
(ns clj-smartystreets.core
(:require [clj-http.client :as client]
[clojure.string :refer [join blank?]]
[cheshire.core :refer [generate-string]])
(:import [clojure.lang Sequential]))
(def street-address-url "https://api.smartystreets.com/street-address")
(def zipcode-url "https://us-zipcode.api.smartystreets.com/lookup")
(def street-address-request-fields [:street :street2 :secondary :city :state :zipcode :lastline :addressee :urbanization])
(def zipcode-request-fields [:city :state :zipcode])
(defn- do-request
"make a call to the smartystreets service"
[url auth queries]
(client/post url {:as :json :query-params auth
:body (generate-string queries)
:headers {"X-Include-Invalid" "true"}}))
(defn- query->response [responses idx query]
(first (filter #(= idx (:input_index %)) responses)))
(defn- fetch [endpoint fields]
(fn [auth address-queries]
(let [responses (->> (map #(select-keys % fields) address-queries)
(do-request endpoint auth)
:body)]
(map-indexed (partial query->response responses) address-queries))))
(defmulti norm (fn [fun auth coll] (type coll)))
(defmethod norm Sequential [fun auth coll]
(fun auth coll))
(defmethod norm :default [fun auth coll]
(first (fun auth [coll])))
(def street-address
(partial norm (fetch street-address-url street-address-request-fields)))
(def zipcode
(partial norm (fetch zipcode-url zipcode-request-fields)))
(def zipcode->city-state
(partial norm
(fn [auth zipcodes]
(->> zipcodes
(map (fn [zipcode] {:zipcode zipcode}))
(zipcode auth)
(map :city_states)
(map first)))))