This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-06-28
Channels
- # babashka (10)
- # beginners (140)
- # cider (6)
- # clj-kondo (10)
- # cljs-dev (39)
- # cljsrn (6)
- # clojars (1)
- # clojure (23)
- # clojure-europe (2)
- # clojure-spec (7)
- # clojure-uk (6)
- # clojurescript (1)
- # conjure (16)
- # cursive (3)
- # datomic (3)
- # emacs (6)
- # fulcro (13)
- # graalvm (3)
- # malli (8)
- # meander (4)
- # off-topic (43)
- # pathom (1)
- # pedestal (15)
- # re-frame (13)
- # reagent (3)
- # sci (25)
- # shadow-cljs (26)
- # sql (9)
- # testing (34)
- # tools-deps (80)
I was working on how to organize resolver code - mainly for common concerns like auth and made an interesting connection - combining pedestal interceptors with pathom-connect transform....
(require
[io.pedestal.interceptor.chain :as chain]
[io.pedestal.interceptor.helpers :as ih])
(def response-key :pathom-interceptors/response)
(defn assoc-response [in-map response]
(assoc-in in-map [:env response-key] response))
(defn get-response [in-map]
(get-in in-map [:env response-key]))
(defn response-interceptor
[{:keys [opts env params] :as in}]
(let [{::pc/keys [mutate resolve]} opts
response (get-response in)]
(if response
in
(if resolve
(assoc-response in (resolve env params))
(assoc-response in (mutate env params))))))
(defn interceptors->pathom-transform
"Executes vector of interceptors on a pathom resolver or mutation.
Each interceptor is passed a single map (the environment) which has the keys:
:opts - The definition-time pathom resolver or mutation map of options.
:env - The pathom connect environment for the resolver or mutation passed by pathom at request-time.
:params - The params to the resolver or the mutation.
Responses are set on the env like so:
(assoc-response env {:my-pathom-resp :value})
"
[interceptors]
(fn pathom-transform*
[{::pc/keys [mutate resolve] :as opts}]
(let [interceptors (conj interceptors (ih/after response-interceptor))]
(cond
resolve
(assoc opts ::pc/resolve
(fn [en params]
(let [out (chain/execute {:opts opts :env en :params params} interceptors)]
(get-response out))))
mutate
(assoc opts ::pc/mutate
(fn [en params]
(let [out (chain/execute {:opts opts :env en :params params} interceptors)]
(get-response out))))
:else (throw
(Exception.
(str "Attempting to use interceptor transform on a map that does not have a resolve or mutate.")))))))
(defn auth-user-interceptor
[{:keys [opts env] :as in}]
(let [{:auth/keys [no-user-msg]
:or {no-user-msg "You must be logged in to perform this action."}} opts
{:keys [current-user]} env]
(cond-> in (not current-user)
(assoc-response (server-error no-user-msg)))))
(pc/defmutation create-thing-mutation
[{:keys [current-user] :as env} props]
{:auth/no-user-msg "You must be logged in to create a thing."
::pc/transform (interceptors->pathom-transform [(ih/before auth-user-interceptor)])}
;; do mutation
)