Fork me on GitHub
#pathom
<
2019-11-12
>
mruzekw17:11:03

Hi there, I’m building a backend with pathom in CLJS. I’m following the Fulcro guide and I’m at the point where I’m playing with parsers in the REPL.

mruzekw17:11:50

However, when I pull my parser namespace into the REPL and call api -parser it gives me this error:

TypeError: Cannot read property 'ReadPort' of undefined
    at $wsscode$common$async_cljs$chan_QMARK_ [as chan_QMARK_] (/Users/mruzekw/Code/serverlesstest/myapp/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/com/wsscode/common/async_cljs.cljs:7:3)

mruzekw17:11:21

Can the ns be loaded and the parser without a running server?

mruzekw17:11:27

I’m sort of lost where to go from here

mruzekw17:11:44

For the record I’m trying to run:

(api-parser [{[:person/id 1] [:person/name]}])

mruzekw17:11:03

And the parser and resolvers are defined exactly as in the Fulcro section

souenzzo17:11:55

@mruzekw can you share the full stacktrace? ( *e on repl )

mruzekw17:11:13

TypeError: Cannot read property 'ReadPort' of undefined
    at $wsscode$common$async_cljs$chan_QMARK_ [as chan_QMARK_] (/Users/mruzekw/Code/serverlesstest/myapp/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/com/wsscode/common/async_cljs.cljs:7:3)
    at com$wsscode$pathom$core$wrap_parser_exception_$_wrap_parser_exception_internal (/Users/mruzekw/Code/serverlesstest/myapp/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/com/wsscode/pathom/core.cljc:830:7)
    at /Users/mruzekw/Code/serverlesstest/myapp/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/com/wsscode/pathom/connect.cljc:1695:13
    at $wsscode$pathom$core$wrap_normalize_env_internal__3 [as cljs$core$IFn$_invoke$arity$3] (/Users/mruzekw/Code/serverlesstest/myapp/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/com/wsscode/pathom/core.cljc:1009:7)
    at $wsscode$pathom$core$wrap_normalize_env_internal__2 [as cljs$core$IFn$_invoke$arity$2] (/Users/mruzekw/Code/serverlesstest/myapp/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/com/wsscode/pathom/core.cljc:1006:4)
    at myapp$backend$parser$api_parser (/Users/mruzekw/Code/serverlesstest/myapp/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/myapp/backend/parser.cljs:47:3)
    at cljsEval (<eval>:1:41)
    at global.SHADOW_NODE_EVAL ([stdin]:105:10)
    at Object.shadow$cljs$devtools$client$node$node_eval [as node_eval] (/Users/mruzekw/Code/serverlesstest/myapp/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/shadow/cljs/devtools/client/node.cljs:24:1)
    at /Users/mruzekw/Code/serverlesstest/myapp/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/shadow/cljs/devtools/client/node.cljs:49:13

souenzzo17:11:44

looks like that you are mixing -async things with non-async things . But I can't understand how.. You are using some p/async-parser or pc/mutate-async or some -async reader?

mruzekw17:11:16

The parser is defined as:

(def pathom-parser
  (p/parser {::p/env     {::p/reader                 [p/map-reader
                                                      pc/reader2
                                                      pc/ident-reader
                                                      pc/index-reader]
                          ::pc/mutation-join-globals [:tempids]}
             ::p/mutate  pc/mutate
             ::p/plugins [(pc/connect-plugin {::pc/register resolvers})
                          p/error-handler-plugin]}))

wilkerlucio17:11:01

Fulcro by default assumes you are using the parallel parser, the parallel / async return channels, but the normal one doesn't, look for a place with <!! and remove it, so it doesn't try to read from a map 🙂

wilkerlucio17:11:15

that's my guess ,but let me know if its something different

wilkerlucio17:11:49

how are you integrating this parser? this is a cljs parser, right?

mruzekw17:11:07

Yep, CLJS. Plan on using it in an AWS Lambda

wilkerlucio17:11:16

(for cljs you probably want the async-parser, otherwise you wont be able to do anything async, like http requests)

wilkerlucio17:11:31

ah, on lamba, ok, this way you may be ok with serial, hehe

wilkerlucio17:11:06

how did you setup the fulcro remote for it?

souenzzo17:11:31

can't reproduce. https://gist.github.com/souenzzo/58cf26321fc2ab91fde9dbcef9b3781a Should be something "external" (as fulcro wraper)

mruzekw17:11:34

Right now I’m just hard coding some maps and resolving from there

mruzekw17:11:14

I’m not really in the Fulcro part of the set up just yet

mruzekw17:11:25

Just trying to play with EQL, Pathom, and resolvers

wilkerlucio17:11:59

strange, can you post the full code of what you trying on a gist?

mruzekw18:11:07

I’m just loading that ns right now and trying to run api-parser

wilkerlucio18:11:39

why do you have 2 parsers?

mruzekw18:11:57

I was trying either

mruzekw18:11:00

Neither of them work

wilkerlucio18:11:57

the parallel will return a channel

wilkerlucio18:11:03

but I'm finding very strange that error you got

wilkerlucio18:11:05

for read port

wilkerlucio18:11:23

that's nothing much else going on around?

wilkerlucio18:11:49

but also, that setup on the regular parser seems old

wilkerlucio18:11:52

(def pathom-parser
  (p/parser {::p/env                  {::p/reader [p/map-reader
                                                   pc/reader2
                                                   pc/open-ident-reader
                                                   p/env-placeholder-reader]}
             ::p/placeholder-prefixes #{">"}
             ::p/mutate               pc/mutate
             ::p/plugins              [(pc/connect-plugin {::pc/register resolvers})
                                       p/error-handler-plugin
                                       p/trace-plugin]}))

wilkerlucio18:11:24

one detail, on your parallel. you were using a wrong variable on the resolvers

👍 4
wilkerlucio18:11:34

also, you don't need double list here: (def resolvers [[person-resolver list-resolver]])

wilkerlucio18:11:44

it gets flatten, the reason to support vectors is jjust to make composition easy

wilkerlucio18:11:49

but in pratice its a flat list

mruzekw18:11:21

Doesn’t seem to work either

mruzekw18:11:34

So p/parser is just a sync parser and should just return the result, right? No channel needed?

✔️ 4
mruzekw18:11:57

Why would it be touching async stuff then?

wilkerlucio18:11:33

that's what is bugging me, makes no sense 😛

wilkerlucio18:11:52

this repository is working, you can clone and run shadow-cljs watch app

wilkerlucio18:11:58

it logs a parser result to the console

wilkerlucio18:11:21

I hope you may find a difference with your setup

mruzekw18:11:17

Thanks, I’ll give it a look.

mruzekw18:11:28

Using a Node env wouldn’t make a difference, would it?

wilkerlucio18:11:07

it should be the same

mruzekw18:11:36

It does work with your repo

mruzekw18:11:45

I’ll see if I can reconcile with my setup

mruzekw18:11:06

Okay it seems to be working now.

mruzekw18:11:10

Thank you both!

mruzekw18:11:16

I’m not sure if my shadow-cljs compiler was watching for changes. Thus the code you originally gave me probably worked, but wasn’t loaded when I reloaded the ns in the REPL

wilkerlucio18:11:03

and state crashes the day again, hehe

🙌 4
wilkerlucio18:11:24

you should check if that behavior was expected at #shadow-cljs

mruzekw18:11:06

kk, thanks

mruzekw18:11:00

What’s the advantage of Pathom over plain GraphQL other than EDN and EQL?

mruzekw18:11:54

If I were to argue to non-Clojure developers why this is valuable, what would I say?

mruzekw18:11:06

Is it most valuable in the context of Fulcro?

wilkerlucio18:11:48

@mruzekw to me, when comparing Pathom with GraphQL, the main difference is on the modeling, GraphQL uses a strict type schema, were types must defined ahead of time, while pathom embraces a very flexible property based modeling, where the central pieces are the properties, not the entities. this has a bunch of implications down the road, one example is when you try to combine multiple graphs, in the GraphQL case, its a pain in the ass, because you can't extend any of the types, also, because of the lack of namespaces, there is a good change you end up with conflicting types, they have workarounds, but IMO they fail to address the main issue here, that is, you need some way to talk about information that's not ambiguous.

wilkerlucio18:11:45

in this sense, pathom things more like RDF, and encourage the use of long names (eg: :youtube.video/id instead of :id), those names enable multiple systems to live in the same space, this also enables that you make connections around those names. this way pathom makes easier to combine different graphs, in my work, our system deals with tons of REST endpoints, plus 2 different GraphQL sources, and you can get data from all of them in a single query, I find this property beautiful 🙂

wilkerlucio18:11:15

and the trick for the GraphQL was simple, we just prefix all the names imported, so they wont collide

wilkerlucio19:11:21

and when you have the base on properties, you can have style of resolvers you are seeing in Connect, that effectivelly kills the need for a controler, the index can do the composition for you

wilkerlucio19:11:44

does some of that makes sense to you?

mruzekw19:11:39

From a high-level it does. I haven’t written a plain GraphQL resolver/server to completely understand the index part yet

mruzekw19:11:05

I like the idea of property-based modeling, seems more dynamic