Fork me on GitHub
#fulcro
<
2021-02-25
>
Casey17:02:59

Is there a trick to be able to hot-reload pathom resolvers and mutations without restarting the http-server/middleware?

tony.kay21:02:57

Here’s what I do: Make your own macro for defresolver and defmutation that do the following: • Copy the body into a function with an alternate symbol (e.g. my-resolver-impl) • Emit the resolver with the desired symbol, but have it just call the function. Now when you reload the resolver it redefines the symbol for the generated function, which is what the embedded resolver will call.

tony.kay21:02:08

You can do it without a macro just by doing that by hand, of course

tony.kay21:02:38

something like this

tony.kay21:02:40

(defmacro defresolver [& args]
  (let [{:keys [sym arglist doc config body]} (futil/conform! ::mutation-args args)
        internal-fn-sym (symbol (str (name sym) "__internal-fn__"))
        config          (dissoc config :check :ex-return)
        env-arg         (first arglist)
        params-arg      (second arglist)]
    `(do
       ;; Use this internal function so we can dynamically update a resolver in
       ;; dev without having to restart the whole pathom parser.
       (defn ~internal-fn-sym [env# params#]
         (let [~env-arg env#
               ~params-arg params#
               result# (do ~@body)]
           result#))
       (pc/defresolver ~sym [env# params#]
         ~config
         (~internal-fn-sym env# params#)))))

Casey09:02:00

Ah interesting idea to wrap it in a macro! Thanks. futil/conform is from om.fulcrologic.fulcro.algorithms.do-not-use I suppose? I suppose you could use the same idea to apply authorization requirements to certain mutations and resolvers?

tony.kay16:02:55

ah, yeah, I didn’t show the specs/conform, but basically it’s just argument parsing

dvingo17:02:19

Maybe you can put the creation of your parser behind a function (that is created on every request), then use the var trick, for example: https://github.com/pedestal/pedestal/blob/master/samples/hello-world/src/hello_world/server.clj#L32 Where routes becomes your vector of resolvers/mutations ^ you probably don't want to create the parser on each request in deployed environment though

Casey09:02:00

Ah interesting idea to wrap it in a macro! Thanks. futil/conform is from om.fulcrologic.fulcro.algorithms.do-not-use I suppose? I suppose you could use the same idea to apply authorization requirements to certain mutations and resolvers?