Fork me on GitHub
#graphql
<
2020-04-22
>
oliy10:04:20

I suppose it's going to be way too hard to move away from antlr in order to support cljs?

vlaaad14:04:17

oh hi there! I had a pleasant experience integrating lacinia into my web service at work. There is one thing that bothered me though: why does documentation suggest to keep schema as edn file and than walk it with attach-resolvers to update resolvers? I just defined everything in code with resolver functions right in the schema — I think that’s simple and makes total sense…

gklijs15:04:46

Not sure, how do you make sure your not accidentally change the schema?

vlaaad15:04:53

Because it's an immutable value? And code is under version control? Not sure I understand your question.

hlship16:04:13

It's what works for us, with a fairly large schema. But it's all just data, so you can do what you want ... mix it up, a little EDN, a little GraphQL schema language, a bit of data manipulation, inject some documentation ... you get to decide.

gklijs03:04:20

@U47G49KHQ it's possibly some code change might accidentally change the schema right? Having version control is no safe guard against that, just allows you to go back. Expedia Group, the creators of graphql-kotlin, use a tool from appolo to check the generated schema for backwards incompatible schema changes each commit. If the whole schema is in one edn file, it's less likely to accidently change I think.

vlaaad06:04:25

@U26FJ5FDM I don’t see how file extension .edn vs .clj helps with these “accidental changes”. I don’t know anyone who randomly changes neither their code, nor resources. The difference between embedding schema in code vs using external file is a layer of indirection and post-processing that is required because of that indirection. As edn, finding actual resolver requires searching for usages of attach-resolvers:

{:type (non-null :human)
 :args {:id {:type String}}
 :resolve :human}
As clj, finding actual resolver is just a “go to definition”:
{:type '(non-null :human)
 :args {:id {:type 'String}}
 :resolve human}

gklijs06:04:27

Yes, but it keeps everything together. Randomly and accidentally are different things..

vlaaad06:04:05

what keeps everything together?

gklijs10:04:26

If you put all the types and resolvers in the schema.edn.

Lennart Buit20:04:06

Hey, we are using lacinia.pedestal here, and the other day I was adding an interceptor that sends errors to rollbar to our pedestal stack. One thing I noticed while implementing is that exceptions thrown in lacinia resolvers are catched as of 0.36.0, and passed as values into lacinia.pedestal. The query executor in lacinia.pedestal then consumes this exception before it reaches any of the error interceptors. Is that something you are perhaps open to change. I am open to create an issue, and also to do the work after discussions ^^.

hlship20:04:09

This change was related to allowing the query execution to execute on a pooled thread, with a timeout.

hlship20:04:17

So you could look into replacing the interceptor supplied by Lacinia here.

Lennart Buit20:04:30

You’d say replace the query-executor interceptor, then. In my code

Lennart Buit20:04:40

I was thinking, which is why I am asking. that it may also be possible to split the query-executor in lp in two, one that executes the query and possibly raises and one that applies the result to the context. That way consumers of lp only have to replace this ‘apply query to context’ interceptor, or otherwise, can put an error handling interceptor in between. But I am probably missing something here

hlship20:04:15

No, I think you're on to something, but I'm too busy with urgent work to dive into the code right now.

hlship20:04:57

But the point of inject is to make it possible to amend or substitute interceptors in the default chain easily, even if the composition of the default chain changes between l-p releases.

Lennart Buit21:04:58

Thats cool, urgent work is more important! If you want, I can also file an issue to keep track