pathom

:pathom: https://github.com/wilkerlucio/pathom/ & https://pathom3.wsscode.com & https://roamresearch.com/#/app/wsscode
Tyler Nisonoff 2020-08-10T17:47:26.423200Z

can a pathom mutation utilize resolvers to load data, or can it only utilize parameters explicitly passed to it? for example, if I pass a user/id to the mutation, can i use my already written resolves to load other fields, or would i have to load them from explicitly from whatever data-source Iā€™m using?

souenzzo 2020-08-10T17:52:26.425Z

@tylernisonoff you can do

(pc/defmutation do-thing [{:keys [parser]
                           :as   env} {:user/keys [id]}]
  {::pc/params [:user/id]}
  (let [eid [:user/id id]
        user-with-address (-> env
                              (parser [{eid [:user/id
                                             :user/address]}])
                              (get eid))]
    ...))
Yeah, I agree with you that pc could implement something like ::pc/resolved-params that take ::pc/params as input and resolve it.

souenzzo 2020-08-12T12:43:02.000100Z

Using ::pc/transform

(let [connect-params (fn [{::pc/keys [mutate]
                           ::keys    [connected-params]
                           :as       mutation}]
                       (if connected-params
                         (assoc mutation
                           ::pc/mutate (fn [{:keys [parser] :as env}
                                            [eid & {:as others}]]
                                         (let [result (parser env `[{(~eid ~{:pathom/context others})
                                                                     ~connected-params}])]
                                           (mutate env (get result eid)))))
                         mutation))
      parser (ps/connect-serial-parser
               [(pc/mutation
                  `op {::pc/params        [:a]
                       ::connected-params [:a :b]
                       ::pc/transform     connect-params}
                  (fn [_ params] params))
                (pc/resolver
                  `b {::pc/input #{:a} ::pc/output [:b]}
                  (fn [_ {:keys [a]}]
                    {:b (str [:b a])}))])]
  (parser {} `[(op {:a 42})]))

Tyler Nisonoff 2020-08-10T17:54:08.425100Z

awesome! trying that now

Tyler Nisonoff 2020-08-10T18:02:30.425300Z

perfect ā€” thanks @souenzzo

souenzzo 2020-08-10T18:05:34.425500Z

I use this small helper in my codebase. I don't like the name of this function but it's useful.

souenzzo 2020-08-10T18:05:39.425700Z

(defn get-from-context
  [{:keys [parser] :as env} context query]
  (let [[eid & others] context]
    (-> (parser env `[{(~eid {:pathom/context ~(into {} others)})
                       ~query}])
        (get eid))))
(pc/defmutation do-thing [env params]
  {::pc/params [:user/id]}
  (let [user-with-address (get-from-context env params [:user/id
                                                        :user/address])]
    ...))

1ā¤ļø
wilkerlucio 2020-08-10T19:46:39.426900Z

this is possible to implement with a plugin, the gist of it is to get the source params and run a query using that as the initial context

wilkerlucio 2020-08-10T19:47:09.428Z

you can do a recursive call to the parser (available in the env), setting ::p/entity to be a (atom params), then send the response of that to the mutation, makes sense?

wilkerlucio 2020-08-10T19:47:32.428400Z

ups, just realized @souenzzo already replied :)

Tyler Nisonoff 2020-08-10T19:48:18.428800Z

good to know about the plugin idea too šŸ™‚ thanks!

wilkerlucio 2020-08-10T19:48:37.429400Z

as a suggestion, creating a custom ::pc/transform can make this look nicer

wilkerlucio 2020-08-10T19:48:59.429900Z

plugin, or a function to be used as ::pc/transform

1šŸ‘
wilkerlucio 2020-08-10T19:49:15.430600Z

that way you can cherry pick which mutations should "auto-resolve" params