Last active
September 7, 2022 23:12
-
-
Save dvingo/95e3dc2be3d7d1629079f459b9086a1e to your computer and use it in GitHub Desktop.
Using sieppari to handle the logic in pathom resolvers and mutations
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns space.matterandvoid.pathom-sieppari | |
(:require | |
[sieppari.context] | |
[sieppari.core :as s] | |
[taoensso.timbre :as log])) | |
(defn terminate-if | |
"Takes a function that will be passed the pathom enviroment, if that function returns a non-falsey value | |
the sieppari chain is terminated and whatever is returned from `f` is the response of the chain. | |
Returning nil or false allows the interceptor chain to continue processing." | |
[f] | |
(fn [pathom-env] | |
(if-let [response (f pathom-env)] | |
(sieppari.context/terminate pathom-env response) | |
pathom-env))) | |
(defn response-interceptor | |
"Takes function which is invoked with the env/context, whatever is returned from `f` is used as the :response. | |
Intended to be used to return the final value of an interceptor chain, will set the :response key on the interceptor context." | |
[f] | |
{:enter (fn [env] (assoc env :response (f env)))}) | |
(defn terminate [env resp] (sieppari.context/terminate env resp)) | |
(defn interceptors->resolve-fn | |
"Takes a vector of sieppari interceptors and returns a function that matches the signature for a resolver in pathom 2 | |
i.e.: (fn [env params]), when the returned function is invoked it executes the interceptors chain using sieppari.core/execute. | |
The interceptors only accept one map as context, thus the pathom params (the 2nd argument supplied to resolve/mutate) | |
is assoc'ed onto the pathom env to construct the sieppari interceptors context. | |
" | |
[ints] | |
(assert (vector? ints) "Interceptors must be a vector.") | |
(fn [env params] | |
(let [r | |
(:response (s/execute-context ints (assoc env :params params)))] | |
(def r' r) | |
r))) | |
(comment | |
((interceptors->resolve-fn [ | |
(response-interceptor resp) | |
{:enter (fn [c] (log/info "enter: ") c)} | |
{:leave (fn [c] (log/info "leave: ") c)} | |
]) | |
{:hi 5} nil) | |
(def inc-x-interceptor | |
{:enter (fn [{:keys [request] :as ctx}] | |
(println "ctx: " ctx) | |
(def c' ctx) | |
(update-in ctx [:x] inc))}) | |
(defn another-handler [r] {:another-handler true}) | |
(comment | |
(s/execute-context [inc-x-interceptor | |
{:enter #(do (println "i 1") | |
(assoc % :asbd 400))} | |
{:enter #(do (println "i 2") (assoc % :as2bd 400))} | |
{:enter #(sieppari.context/terminate % {:done true})} | |
{:enter #(do (println "i 3") (assoc % :as3bd 300))} | |
{:enter #(do (println "i 4") (assoc % :as4bd 400))} | |
{:enter #(do (println "i 5") (assoc % :as5bd 500))} | |
] {:x 40} | |
) | |
(s/execute [{:enter #(update-in % [:request :x] inc)} | |
{:enter #(do (println "i 1 " %) (assoc % :asbd 400))} | |
{:enter #(do (println "i 2") (assoc % :as2bd 400))} | |
{:enter #(sieppari.context/terminate % {:done true})} | |
{:enter #(do (println "i 3 2 ") (assoc % :as3bd 300))} | |
{:enter #(do (println "i 4") (assoc % :as4bd 400))} | |
{:enter #(do (println "i 5") (assoc % :as5bd 500) | |
(assoc % :response {:done :yes}))}] | |
{:x 40})) | |
(s/execute [inc-x-interceptor handler another-handler] {:x 40}) | |
(s/execute-context | |
[inc-x-interceptor handler #_another-handler] {:x 40}) | |
) | |
;;; and sample usage | |
(defn assoc-habit-tx-data [{:keys [current-user params] :as env}] | |
(let [habit (habit/make-habit params) | |
new-user (user/add-habit-id current-user habit) | |
habit (habit/make-db-habit habit) | |
tx-data (mapv #(do [::xt/put %]) [habit new-user])] | |
(assoc env :tx-data tx-data :habit habit))) | |
(def assoc-habit-tx-data-int {:enter assoc-habit-tx-data}) | |
(defn submit-tx [{:keys [xtdb-node tx-data]}] | |
(assert (valid-xtdb-tx-data? tx-data)) | |
(log/info "Saving tx data: " tx-data) | |
(xt/submit-tx xtdb-node tx-data)) | |
(def submit-tx-int {:enter submit-tx}) | |
(defn save-habit-response [{:keys [habit]}] habit) | |
(def save-habit-response-interceptor (interceptors/response-interceptor save-habit-response)) | |
(defn save-habit-ints [] | |
[interceptors/check-logged-in-interceptor | |
validate-habit-int | |
assoc-habit-tx-data-int | |
submit-tx-int | |
save-habit-response-interceptor]) | |
(def save-habit | |
{::pc/sym `save-habit | |
::pc/mutate (interceptors->resolve-fn (save-habit-ints))}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment