diff --git a/src/clj_hl7_fhir/core.clj b/src/clj_hl7_fhir/core.clj index cdc22a2..00ac48a 100644 --- a/src/clj_hl7_fhir/core.clj +++ b/src/clj_hl7_fhir/core.clj @@ -5,13 +5,13 @@ (:use [camel-snake-kebab] [clj-hl7-fhir.util])) +(def ^:private base-params {:_format "json"}) + (defn- ->fhir-resource-name [x] (name (->CamelCase x))) (defn- fhir-get-request [base-url resource-url & [params]] - (let [query (cond - (sequential? params) (->> params (concat [:_format "json"]) (kv-vector->query)) - :else (merge {:_format "json"} params))] + (let [query (map->query-string (merge base-params params))] (http-get-json (build-url base-url resource-url query)))) (defn- ->search-param-name [parameter & [modifier]] @@ -77,7 +77,7 @@ :else (-> value str escape-parameter))) -(defn- search-params->query-kvs [params] +(defn- search-params->query-map [params] (->> params (apply concat) (map @@ -86,7 +86,12 @@ (str (if-not (= "=" operator) operator) (format-search-value value))])) - (apply concat))) + (reduce + (fn [m [name value]] + (if (contains? m name) + (update-in m [name] #(conj (if (vector? %) % [%]) value)) + (assoc m name value))) + {}))) (defn- get-bundle-next-page-url [bundle] (->> (:link bundle) @@ -175,11 +180,12 @@ reference: search: http://hl7.org/implement/standards/fhir/http.html#search" - [base-url type & params] + [base-url type where & params] (let [resource-name (->fhir-resource-name type) url-components ["/" resource-name]] (fhir-get-request base-url (apply join-paths url-components) - (search-params->query-kvs params)))) - + (merge + (search-params->query-map where) + (apply hash-map params))))) diff --git a/src/clj_hl7_fhir/util.clj b/src/clj_hl7_fhir/util.clj index 75a7a7c..41f00bb 100644 --- a/src/clj_hl7_fhir/util.clj +++ b/src/clj_hl7_fhir/util.clj @@ -18,6 +18,22 @@ (.setTimeZone df tz) (.format df date)))) +(defn map->query-string [m] + (->> m + (reduce + (fn [query-values [param-name value]] + (concat + query-values + (map + #(str (url-encode (name param-name)) + "=" + (url-encode (str %))) + (if (vector? value) value [value])))) + []) + (interpose "&") + (flatten) + (apply str))) + (defn kv-vector->query "should really be using cemerick.url/map->query in all cases except when you need 2 values under the name name in the query string (such as with FHIR's date 'between' search support)"