This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-01-25
Channels
- # aleph (12)
- # announcements (2)
- # beginners (40)
- # calva (8)
- # cider (26)
- # cljs-dev (71)
- # cljsrn (2)
- # clojure (122)
- # clojure-dev (9)
- # clojure-europe (2)
- # clojure-nl (2)
- # clojure-spec (42)
- # clojure-uk (20)
- # clojurescript (86)
- # cursive (15)
- # data-science (1)
- # datomic (42)
- # duct (4)
- # emacs (33)
- # events (1)
- # figwheel-main (2)
- # fulcro (33)
- # jobs (2)
- # jobs-discuss (46)
- # kaocha (13)
- # leiningen (9)
- # off-topic (62)
- # pathom (75)
- # quil (2)
- # re-frame (6)
- # reagent (13)
- # reitit (3)
- # shadow-cljs (52)
- # spacemacs (3)
- # specter (17)
- # sql (6)
- # tools-deps (2)
- # vim (3)
- # yada (28)
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
Perhaps it is the right thing to do and elide in the post-process parser
@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
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
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 đ
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
ok, let's try to make sense of it đ
one thing to consider when splitting/merging resolvers is that how much work is been done
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
but computed data must be in a separated resolver most of the times
this way you can optimize how much computation is been done
the output will have only what the user asks, so no unnecessary bandwidth will be used
from what kind of you source you are pulling the data?
Datomic - so basically a thin wrapper over (d/pull (db) query eid)
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
and relations can be defined using new resolvers
its ok to output a lot of things from the resolver, and datomic been all in memory (cached) also helps
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
This is when requesting attributes that aren't guaranteed to be present. Can I elide not-found
on specific resolvers?
Thanks for your help
ah, yes, for eliding not found is quite easy
you can use a post-process plugin: ::p/plugins [... (p/post-process-plugin p/elide-not-found)]
something like this
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
So ignore - and thanks
@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?
@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
Ah! I was trying to find a written comparison in Pathomâs doc. I should have checked EQLâs doc as well
if I try to describe the big picture in short, the major difference is about the decision of what are the building blocks
GraphQL is all based on types/containers, the primary building blocks are the types, they are referenced all the time in the whole system
while pathom uses a more datomic/spec like mindset, where the attributes are the building blocks, not the types/containers
and this mindset is what makes the things from pathom possible
by having the attributes as first class we can talk about then without ever have to reference (or name) aggregates
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 đ
@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?
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
@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)
@hmaurer on the contrary, namespaces are very important for Pathom, and for attribute modeling in general I think
without that you get only gigantic tedios to type things all the time (remember C)
oh, how come? Could you write :user-email
instead of :user/email
and get essentially the same results?
yeah, we also use it for some features, the placeholder nodes for example, they are based on namespaces
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
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
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
yeah, agreed, but they really help on the mindset
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
I find hard to convince a JS programmer that: {"youtubeVideoId": "..."}
is better than {"id": "..."}
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?
yeah, resolver level sounds right, so you can make it as specific as you need (up to each attribute)
there is a cool (pending docs) feature in pathom that allows you to write interceptors (kind like pedestal) for resolvers
this way you could make some generic security plugin and wrap resolvers with then as you see fit
looks like this:
Also, unrelated but do you know https://www.graphile.org/postgraphile/ ?
thats nice, and since we can "pull" graphqls into Pathom, taht could be used strait out đ
caveat: there are some limitations on graph to graph requirements at this point, but they are been worked out
@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
@wilkerlucio out of curiosity, what are the graph to graph m=limitations?
@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}}}
@wilkerlucio ah, I see. by the way, unrelated question: do you currently support documentation on Pathom attributes? And introspection on said docuemntation?
no docs directly from pathom, but specs are getting docstrings, so you can just use that
@wilkerlucio oh are they? I hadnât heard, thatâs great. Does Pathom exposes specs someone through introspection queries?
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 đ
no, its your job to have the specs on the client, since they are code I can't garantee transmission
yup, I'm getting an example for you
this is what transform usage looks like:
(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"))))))})
so you can generative what goes in the ::pc/transform
here you can find some built-in transform functions: https://github.com/wilkerlucio/pathom/blob/master/src/com/wsscode/pathom/connect.cljc#L1244-L1275