This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-06-08
Channels
- # babashka (9)
- # beginners (43)
- # biff (4)
- # calva (11)
- # cider (6)
- # clerk (1)
- # clj-kondo (4)
- # cljs-dev (6)
- # clojure (82)
- # clojure-berlin (1)
- # clojure-europe (42)
- # clojure-nl (1)
- # clojure-norway (182)
- # clojure-quebec (1)
- # clojure-uk (19)
- # clojurescript (6)
- # datahike (1)
- # emacs (30)
- # fulcro (5)
- # honeysql (6)
- # hyperfiddle (12)
- # lambdaisland (8)
- # malli (11)
- # off-topic (36)
- # pathom (26)
- # pedestal (1)
- # portal (25)
- # practicalli (1)
- # rdf (29)
- # re-frame (17)
- # reitit (1)
- # releases (1)
- # sci (37)
- # shadow-cljs (15)
- # vim (10)
- # xtdb (13)
Hello, in the 2-arity of defresolver
the first parameter (the env) is not a part of the inferred input for that resolver when inspecting (index)
. Is there a reason that is? Is there some way to get that to show as an inferred input? (evaluation of (index)
will be in the thread.
(ns sandbox-clojure.core
(:require
[com.wsscode.pathom3.connect.operation :as pco]
[com.wsscode.pathom3.connect.indexes :as pci]))
(pco/defresolver full-name-resolver
[{:keys [first-name]}
{:keys [last-name]}]
{:full-name (str first-name " " last-name)})
(defn index
[]
(-> {:first-name "ben"}
(pci/register
[full-name-resolver])))
(index)
{:first-name "ben",
:com.wsscode.pathom3.connect.indexes/index-resolvers
#:sandbox-clojure.core{full-name-resolver
{:config
#:com.wsscode.pathom3.connect.operation{:input [:last-name],
:provides {:full-name {}},
:output [:full-name],
:inferred-input [:last-name],
:op-name sandbox-clojure.core/full-name-resolver,
:requires {:last-name {}}},
:resolve #function[sandbox-clojure.core/full-name-resolver--19736]}},
:com.wsscode.pathom3.connect.indexes/index-attributes
{:last-name
#:com.wsscode.pathom3.connect.indexes{:attr-id :last-name,
:attr-provides {:full-name #{sandbox-clojure.core/full-name-resolver}},
:attr-input-in #{sandbox-clojure.core/full-name-resolver},
:attr-leaf-in #{sandbox-clojure.core/full-name-resolver}},
:full-name
#:com.wsscode.pathom3.connect.indexes{:attr-id :full-name,
:attr-reach-via {#{:last-name} #{sandbox-clojure.core/full-name-resolver}},
:attr-output-in #{sandbox-clojure.core/full-name-resolver},
:attr-leaf-in #{sandbox-clojure.core/full-name-resolver}}},
:com.wsscode.pathom3.connect.indexes/index-io {#{:last-name} {:full-name {}}},
:com.wsscode.pathom3.connect.indexes/index-oir
{:full-name {{:last-name {}} #{sandbox-clojure.core/full-name-resolver}}}}
What are you trying to do? Your resolvers can just use what’s in the environment to satisfy the return of the stated outputs. But one way to do what I’m guessing you are trying to do would be to have a resolver that outputs your properties simply from the environment (eg current user) and then use those properties in your other resolvers. You’ll need a 2-arity resolver but with no inputs so it basically forms an edge of your graph.
I had jumped to inspecting the index, but more directly, when using ::pcr/wrap-resolve
the input
value is never an env value, only items from the entity. I would ideally like to write a plugin which can validate that the resolver is receiving the expected (required) env values.
hello @U0247T34DQU, the arities 0 and 1 are suggars that only exist in defresolver
macro, in reality every resolver must have arity 2, where env comes first, input last, is that what you see when you are writing a plugin? maybe I'm not getting your issue yet
The issue I am having is that when writing a plugin with ::pcr/wrap-resolver
there is never any reference to any of the keys or values that are present in the env
parameter, only keys/values on the entity are available from what I've seen
I work with @U0247T34DQU so joining in to rephrase the question.
When we build our index, we put configuration data in the env
, that our resolvers later read from the env
. We'd like to do validation at initialization time that all the env
keys used by our resolvers are present in the index at initialization time. For keys used from the entity
, defresolver
will automatically infer the resolver's dependencies, and those dependencies are visible in the index. Is there a similarly easy way to automatically infer the resolver's dependencies on the env
map too?
Hi. I would do this at the time of building your environment. Eg if you’re building your env as part of integrant, you might check the passed in env meets your specification.
Are you looking to dynamically spec the env based on the resolvers?
Yep, that's the goal. The question is how to write the validation function without duplicating the knowledge of what the resolvers depend on.
So I don’t worry about that for two reasons. Firstly I build my environment declaratively using integrant - so I know what’s in my environment and could check it at initialisation time based on the list of resolvers I’m using. Secondly most of my resolvers delegate very much to functions - so that they are simply marshalling properties and leave anything complex to a number of functions. I use Clojure spec to spec those functions so would immediately get a spec error if during dev my environment isn’t what it should be. The final approach would be to spec your env in a resolver- you could define your own macro that calls defresolver (or builds a resolved manually) that takes a spec and checks the env when it is called. Perhaps Wilker has a cleverer way!
Pathom doesn't capture the inferred keys on env, I think this is a brittle way to check for required dependencies. Pathom does it for inputs for convenience, so in many cases it helps you avoid having to type the destructuring + the value of ::pco/input
. If you want to do such thing, you need to make your own macro around defresolver
to capture the env destructuring, this way you can collect this data in a way that makes sense for your approach
I'm curious about which part is brittle. Is it the destructuring inference that's brittle? Or is it the use of that information that is brittle?
maybe I was a bit harsh on that one, quite depends on how you use it. the problematic scenario that I imagine goes like this:
(defresolver something [env input] {:foo (:bar env)})
as long as all your users do the destructuring, you will know the deps, but if the user writes code like above, than you can't know about :bar
dependency
this gets harder if env gets pushed down more in the stack, it gets harder and harder to predict the usages
That kind of key access works for env
because env
is the entire map, whereas the entity is narrowed like select-keys
to only the input attrs that Pathom knows about, so arbitrary key access on they entity doesn't work in the body.
So I understand why we wouldn't necessarily infer the env keys
yeah, and IME env
tends to be something you just push down, so helper functions can extract proper data from it (like a token to make some API call for example)
since env
is about the context of whats going on, while input
is semantically the actual data for the operation
We don't usually have very deep bodies in our resolver. The use of an env key is always pretty close to where it is destructured from the resolver/mutation signature
Is there an easy way to reuse the inference code from entities for the env too? I looked at the code and it didn't look configurable to do that, but I could hack something together with a little guidance.
sure, its very much based on specs (using conform), so you should be able to reuse parts of it, let me check which parts that would be
this is the spec that does most of the work: https://github.com/wilkerlucio/pathom3/blob/d620bd2ef499e410c37db4cc74934c6a9b4bb165/src/main/com/wsscode/pathom3/connect/operation.cljc#L298-L305
and you might want to reuse this fn as well: https://github.com/wilkerlucio/pathom3/blob/d620bd2ef499e410c37db4cc74934c6a9b4bb165/src/main/com/wsscode/pathom3/connect/operation.cljc#L335-L359
Thanks! We'll give this a closer look.