In the plugin:
(defn sample-resolver-error-wrapper [resolver-error]
(fn [env ast error]
(let [e (resolver-error env ast error)]
; you may modify the error here
e)))
what does resolver-error do as oppose to using error directly?does the error markings on state, and fail-fast (on strict mode): https://github.com/wilkerlucio/pathom3/blob/4093b90f2afef9bb22123a1748e6442d5be2cdb4/src/main/com/wsscode/pathom3/connect/runner.cljc#L327-L337
Should it be possible to have a resolver that depends on graphql inputs? I seem to be seeing an error in the gql planner for something like this:
(resolver :input [:gql/a :gql/b] :output [:something])
[:gql/a
:gql/b
:something]
The planner seems to put the resolving of all of these at the same level, instead of marking :something as a dep of :gql/a and :gql/b , and thus isn't able to resolve :somethingyeah, depending on how you organize the query Pathom may need to split it in pieces (getting your slow case), it should be able to forward in one go when that matches a possible GraphQL query on the other end. please let me know if you see it behaving wrongly
For the future curious, we have a connection/edge simplifier for our codebase, since strawberry (python gql) likes to force connections and edges in for no reason. I ended up modifying our driver for that to be inside the gql interface logic, instead of in pathom middleware.
This particularly seems to be an issue with nested inputs. E.g.
(lib.pco/defresolver resolver-ancillary-markets
[{:ops.Asset/keys [ancillaryMarkets]}]
{:ops.Asset/ancillary-markets (mapv keyword ancillaryMarkets)})
(lib.pco/defresolver resolver-clr-resource
[env
{{clr :ops.QSEMetadata/clrResourceCode} :ops.Asset/qseMetadata}]
{::pco/inputs [{:ops.Asset/qseMetadata [:ops.QSEMetadata/clrResourceCode]}]}
{:ops.Asset/clr-resource-code clr})
[{[:ops.Asset/id 1]
[:ops.Asset/id
:ops.Asset/name
:ops.Asset/ancillary-markets
#_:ops.Asset/clr-resource-code]}]
=>
{[:ops.Asset/id 1]
{:ops.Asset/id 1,
:ops.Asset/ancillary-markets [:reserves :reg_down :reg_up],
:ops.Asset/name "example_battery_central_tz_subhourly"}}
[{[:ops.Asset/id 1]
[:ops.Asset/id
:ops.Asset/name
:ops.Asset/ancillary-markets
:ops.Asset/clr-resource-code]}]
=>
{[:ops.Asset/id 1]
{:ops.Asset/id 1,
:ops.Asset/ancillary-markets :com.wsscode.pathom.core/not-found,
:ops.Asset/clr-resource-code :com.wsscode.pathom.core/not-found,
:ops.Asset/name :com.wsscode.pathom.core/not-found}}The dynamic resolver for GQL doesn't seem to want to resolve the nested Asset requirements. Here's the finalized node plan for that:
{:com.wsscode.pathom3.connect.operation/op-name
ops/pathom-entry-dynamic-resolver,
:com.wsscode.pathom3.connect.planner/expects
{:ops.Asset/ancillaryMarkets {},
:ops.Asset/name {},
:ops.Asset/qseMetadata {}},
:com.wsscode.pathom3.connect.planner/foreign-ast
{:children
[{:dispatch-key :ops.Asset/name, :key :ops.Asset/name, :type :prop}
{:dispatch-key :ops.Asset/ancillaryMarkets,
:key :ops.Asset/ancillaryMarkets,
:type :prop}
{:dispatch-key :ops.Asset/qseMetadata,
:key :ops.Asset/qseMetadata,
:type :prop}],
:type :root},
:com.wsscode.pathom3.connect.planner/input {:ops.types/Asset {}},
:com.wsscode.pathom3.connect.planner/node-id 1,
:com.wsscode.pathom3.connect.planner/node-parents #{2},
:com.wsscode.pathom3.connect.planner/run-next 11}
Also, the finalized node for running the clr-resource-code seems to only contain qseMetadata as the final requirement, not mentioning at all its' nested requirements.
{:com.wsscode.pathom3.connect.operation/op-name
com.tybaenergy.model.operations.asset/resolver-clr-resource,
:com.wsscode.pathom3.connect.planner/expects
{:ops.Asset/clr-resource-code {}},
:com.wsscode.pathom3.connect.planner/input
{:ops.Asset/qseMetadata {}},
:com.wsscode.pathom3.connect.planner/node-id 6,
:com.wsscode.pathom3.connect.planner/node-parents #{11}}humm, it may be a bug, because it should be fine to have resolvers relying on dynamic inputs
is it possible to give me a repro of it?
I'll try and repro it with the pathom gql example. eta ~1h most likely 🙂
no worries, take your time, and thanks for it
I can't repro it apparently. Looks like there's some collision between our custom gql resolving and the pathom planner. This is what we have for that:
(p.plugin/defplugin wrap-process-for-gql
{::p.eql/wrap-process-ast
(fn [process]
(fn [{:keys [query-params] :as env} ast]
(let [modified-ast (-> ast
(eql/ast->query)
(modify-gql-query env query-params)
(eql/query->ast))
resp (modify-gql-response (process env modified-ast) env)]
resp)))})
This removes the need to describe connections and edges in our frontend queries to simplify the fulcro components. Could this be stomping on our planner? I'm not really sure where to start to fix this 😂🤔... Maybe I have an idea
ok, I've got an idea that sorta works. Here's my problem - I end up with tons of little sub gql queries being spammed out. e.g. if I want to do something like this:
(pco/defresolver films-sorted-by-director
[input]
{::pco/input [{:swapi.Person/filmConnection
[{:swapi.PersonFilmsConnection/films
[:swapi.Film/id
:swapi.Film/director]}]}]}
{::films-sorted-by-director (sort-by :swapi.Film/director
(get-in input
[:swapi.Person/filmConnection :swapi.PersonFilmsConnection/films]))})
; lets create the environment
(def env
(-> {}
; this helper will pull the schema and register it in the environment
(p.gql/connect-graphql
{::p.gql/namespace "swapi"}
request-swapi-graphql)
(pci/register [films-sorted-by-director])))
(comment
; request all people and the title of the films they participate
(p.eql/process
env
[{:swapi.Root/allPeople
[{:swapi.PeopleConnection/people
[:swapi.Person/name
{::films-sorted-by-director [:swapi.Film/director
:swapi.Film/producers]}]}]}]))
this is very slow, because it has to go back and reach out for every Film to get the producer again. However, if I change the resolver to
(pco/defresolver films-sorted-by-director
[input]
{::pco/input [{:swapi.Person/filmConnection
[{:swapi.PersonFilmsConnection/films
[:swapi.Film/id
:swapi.Film/director
:swapi.Film/producers]}]}]}
{::films-sorted-by-director (sort-by :swapi.Film/director
(get-in input
[:swapi.Person/filmConnection :swapi.PersonFilmsConnection/films]))})
I get back a result very quickly, because pathom pre-cached the producer list.screenshot of the planner