Fork me on GitHub
#pathom
<
2019-01-25
>
Andreas Liljeqvist15:01:38

How should I structure resolvers for something that can return a lot of different combinations of attributes? [{[:person/id 1] [:db/id :name :fifty-more-keys-that-might-be-present-in-a-query]}] Listing all possible in [::pc/output []] could work, but then a lot will be returned with :pathom.something/not-found

Andreas Liljeqvist15:01:03

Perhaps it is the right thing to do and elide in the post-process parser

wilkerlucio15:01:34

@andreas862 if what you have is some heterogeneous list (having multiple "types" of return, were the attributes are consistent per type) you can use Union Queries https://github.com/edn-query-language/eql#unions / https://wilkerlucio.github.io/pathom/#_union_queries

wilkerlucio15:01:32

connect supports you specifying output declarations using the union feature, one caveat is that the tools doesn't support yet (for auto-complete) but the processing works

wilkerlucio15:01:55

please let me know if that looks right for your case and if you need any help implementing it, might be a good time to get more docs in 🙂

Andreas Liljeqvist15:01:23

Checking your link, but don't know if it is exactly what I want. Trying to specify resolver for an entity where the query is some subset of possible attribs. Exhaustive defresolver for all combinations probably isn't right. Just an ::pc/output all-possible-attribs could be right if I elide not-found. Summary - I probably know too little Pathom to think about the problem in the right way

wilkerlucio15:01:45

ok, let's try to make sense of it 🙂

wilkerlucio15:01:01

one thing to consider when splitting/merging resolvers is that how much work is been done

wilkerlucio15:01:30

for example, if you are reading data from some service that returns 5 attributes (or 10, or 100...), since you already have the data, it doesn't make sense to separate it

wilkerlucio15:01:43

but computed data must be in a separated resolver most of the times

wilkerlucio15:01:58

this way you can optimize how much computation is been done

wilkerlucio15:01:26

the output will have only what the user asks, so no unnecessary bandwidth will be used

wilkerlucio15:01:45

from what kind of you source you are pulling the data?

Andreas Liljeqvist15:01:05

Datomic - so basically a thin wrapper over (d/pull (db) query eid)

wilkerlucio15:01:42

yeah, I personally never did a parser using datomic directly some people here did, in general what I see then doing is making a pull like you

wilkerlucio15:01:47

and relations can be defined using new resolvers

wilkerlucio15:01:03

its ok to output a lot of things from the resolver, and datomic been all in memory (cached) also helps

wilkerlucio15:01:06

when some resolver exposes a map, that map is merged in what we call "current entity", this makes that attributes to be locally cached for future access, but they are only exposed if the user asks for then, this means you don't have to manually elide the results, only the requested data will be exposed in the final output

Andreas Liljeqvist16:01:02

This is when requesting attributes that aren't guaranteed to be present. Can I elide not-found on specific resolvers? Thanks for your help

wilkerlucio16:01:12

ah, yes, for eliding not found is quite easy

wilkerlucio16:01:42

you can use a post-process plugin: ::p/plugins [... (p/post-process-plugin p/elide-not-found)] something like this

Andreas Liljeqvist16:01:11

Already using it 🙂 I wanted to know if I could bless specific resolvers instead of global, but I don't think I really have a reason to specify

Andreas Liljeqvist16:01:21

So ignore - and thanks

hmaurer17:01:59

@wilkerlucio Hello 🙂 So as I mentioned the other day I watched your talk on Pathom and have been playing with it yesterday. I have used GraphQL in the past and noticed that Pathom seems a lot neater for extending the knowledge graph than GraphQL is (i.e. adding the ability to fetch youtube data, as per your demo, etc). However I am curious. With your experience writing/using Pathom, what do you think the tradeoffs are? (if you are familiar with GraphQL). As in, do you think Pathom is a straight up better/more flexible way to fetch data and commit mutations? Do you think it is lacking some features that GraphQL has? Do you think they don’t address exactly the same issues?

wilkerlucio17:01:52

@hmaurer hello 🙂 So, lets talk about the constrast, if you did read already I like to mention the differentes I already wrote about in EQL docs: https://github.com/edn-query-language/eql#graphql-comparison

hmaurer17:01:24

Ah! I was trying to find a written comparison in Pathom’s doc. I should have checked EQL’s doc as well

wilkerlucio17:01:26

if I try to describe the big picture in short, the major difference is about the decision of what are the building blocks

wilkerlucio17:01:06

GraphQL is all based on types/containers, the primary building blocks are the types, they are referenced all the time in the whole system

wilkerlucio17:01:22

while pathom uses a more datomic/spec like mindset, where the attributes are the building blocks, not the types/containers

wilkerlucio17:01:09

and this mindset is what makes the things from pathom possible

wilkerlucio17:01:48

by having the attributes as first class we can talk about then without ever have to reference (or name) aggregates

wilkerlucio17:01:33

IMO at this point the major trade-off is the small community (compared to GraphQL), that in consequence means less tools, less people finding bugs... so it goes in a slower pace of change, but that can be good as well 😛

hmaurer17:01:02

@wilkerlucio Thanks for the detailed reply 🙂 The community is always a trade-off for newer projects though! Do you think there is a technical tradeoff in the choice of being attribute-centric?

wilkerlucio17:01:52

more that I try it, more I like it, if you watch Rich's presentations, he talks about that all the time, that's clojure foundations, maybe we miss on tooling, but that's more about things not been ready

hmaurer17:01:57

@wilkerlucio it’s interesting; this is the kind of experiment that would not be as natural in, say, javascript. It feels like namespaces on keywords are a key feature (although afaik Pathom doesn’t care about namespaces as such)

wilkerlucio17:01:19

@hmaurer on the contrary, namespaces are very important for Pathom, and for attribute modeling in general I think

wilkerlucio17:01:36

without that you get only gigantic tedios to type things all the time (remember C)

hmaurer17:01:00

oh, how come? Could you write :user-email instead of :user/email and get essentially the same results?

hmaurer17:01:08

(although of course namespaces are a lot nicer)

wilkerlucio17:01:31

yeah, we also use it for some features, the placeholder nodes for example, they are based on namespaces

wilkerlucio17:01:23

one thing that I see as underused in the clojure community is the namespaced keywords, its getting better after spec, but I like to see more, I think keywords should have NS as much as your code has to have

wilkerlucio17:01:54

the same reasons we use to validate namespaces for code (so we can use multiple functions that have the same name without issues), the same is valid for keywords IMO

hmaurer17:01:56

Maybe I misexpressed myself. What I meant to say is that it seemed to me namespaces aren’t essential for Pathom (in the sense that you could write :user-email instead of :user/email), but they are essential for this kind of attribute-driven approach as they allow you to structure attributes (group user attribuets, etc) in a way that is more organised than key prefixes

wilkerlucio17:01:11

yeah, agreed, but they really help on the mindset

hmaurer17:01:42

Yeah, definitely. That’s what I was trying to say; a project liek Pathom likely wouldn’t arise in JavaScript simply because it doesn’t support key namespaces

👍 1
wilkerlucio17:01:46

I find hard to convince a JS programmer that: {"youtubeVideoId": "..."} is better than {"id": "..."}

😄 2
👍 1
hmaurer17:01:48

It wouldn’t be as “natural”

hmaurer17:01:27

How do you tend to handle security in a Pathom API? (I had the same question about GraphQL). Do you do it at the resolver level?

hmaurer17:01:47

security => access control

wilkerlucio17:01:18

yeah, resolver level sounds right, so you can make it as specific as you need (up to each attribute)

wilkerlucio17:01:59

there is a cool (pending docs) feature in pathom that allows you to write interceptors (kind like pedestal) for resolvers

👍 1
wilkerlucio17:01:15

this way you could make some generic security plugin and wrap resolvers with then as you see fit

wilkerlucio17:01:56

looks like this:

hmaurer17:01:48

Ooh, that sounds very useful. So that feature is already out, just not documented?

wilkerlucio17:01:48

thats nice, and since we can "pull" graphqls into Pathom, taht could be used strait out 🙂

wilkerlucio17:01:07

caveat: there are some limitations on graph to graph requirements at this point, but they are been worked out

hmaurer17:01:33

@wilkerlucio yep, I read that you can “pull” graphql APIs right into Pathom, however I linked it because I tried to contribute to this project but the codebase is a bit of an entangled mess of “plugins” to extend the GraphQL API. From the little I know about Pathom I think it should be a lot more natural to implement

hmaurer17:01:49

I might give that a go after my spring exams; it would be extremely useful

hmaurer18:01:44

@wilkerlucio out of curiosity, what are the graph to graph m=limitations?

wilkerlucio19:01:57

@hmaurer mostly that inputs currently have to be flat, this is a problem to request graphql for example, in the future I want the library to support inputs like: ::pc/input #{{:github.viewer #{:github.user/name}}}

hmaurer19:01:16

@wilkerlucio ah, I see. by the way, unrelated question: do you currently support documentation on Pathom attributes? And introspection on said docuemntation?

hmaurer19:01:19

(like graphql does)

wilkerlucio19:01:52

no docs directly from pathom, but specs are getting docstrings, so you can just use that

hmaurer19:01:01

@wilkerlucio oh are they? I hadn’t heard, that’s great. Does Pathom exposes specs someone through introspection queries?

wilkerlucio19:01:23

about tooling, I've started writing an index explorer last week, I wanna try some ideas on how to visualize and explore the index, so you can search for attributes, and see how to get it, what it offers, specs, examples (from spec generators), maybe some d3 interactive thing, I dunno yet 🙂

wilkerlucio19:01:48

no, its your job to have the specs on the client, since they are code I can't garantee transmission

hmaurer19:01:11

makes sense

wilkerlucio17:01:59

yup, I'm getting an example for you

wilkerlucio17:01:18

this is what transform usage looks like:

wilkerlucio17:01:20

(pc/defresolver my-resolver [_ _]
  {...
   ::pc/transform (fn [resolver-map]
                    (update resolver-map ::pc/resolve
                      (fn [resolve]
                        (fn [env input]
                          (let [res
                                (resolve
                                  (assoc env :modified "env")
                                  (assoc input :input-extra "change-input"))]
                            (assoc res :change-output "too"))))))})

wilkerlucio17:01:33

so you can generative what goes in the ::pc/transform

hmaurer17:01:09

Oh, interesting

hmaurer17:01:13

thanks for that