graphql

orestis 2019-04-04T11:51:47.007100Z

So after writing a few graphql resolvers that do a whole bunch of destructuring of input objects, there seems to be an obvious type system - shaped hole in how the code looks: If the GraphQL schema changes (e.g. a field is renamed or moved around etc etc), the destructuring code doesn’t know.

orestis 2019-04-04T11:53:00.008700Z

I wonder if there is a way to write a macro that does GraphQL aware destructuring — so in addition to having :keys it also knows the graphql input object that it destructures, so it can check (at compile time!) that all keys are present and correct.

3Jane 2019-04-04T11:53:27.009100Z

(if the graphql schema changes, you’ve got bigger problems than destructuring code inside the server, b/c you just broke the api for your clients)

3Jane 2019-04-04T11:54:32.010200Z

(Facebook’s way of resolving that is a “never remove, just add new things” though it can get unwieldy for a smaller company that doesn’t have to handle clients of all the versions)

orestis 2019-04-04T11:54:37.010300Z

I’m my own client 🙂

3Jane 2019-04-04T11:54:41.010500Z

convenient 😄

orestis 2019-04-04T11:55:26.011500Z

I mean, sure, once you go public you need to be very careful about these things. But during development where the API is malleable and might get renamed as we get better at naming things…

3Jane 2019-04-04T11:55:37.011700Z

then the problem converges to wanting an ORM, ie. “if I change my DB schema, my queries stop working”

orestis 2019-04-04T11:56:15.012100Z

One step at a time 🙂 (or, we use MongoDB, what is that Schema you’re talking about?)

orestis 2019-04-04T11:57:08.012600Z

Hey, we are sleeping in the gutter but we are at least looking at the stars 😛

3Jane 2019-04-04T11:57:37.012800Z

https://www.instagram.com/p/BveIVSWAvDP/

3Jane 2019-04-04T11:58:10.013700Z

(fwiw I’m not a fan of multiplying layers, I just like having schema somewhere for reference 😄 )

orestis 2019-04-04T11:59:24.014700Z

I’m overstating it, we do have a schema, but of course it relies on a lot of manual work to keep it up to date. So that’s why since we’re using GraphQL now I’d like to at least make sure we don’t have a second source of bugs.

orestis 2019-04-04T11:59:52.015100Z

An example of what I mean:

(defn my-resolver [context args value]
 (let [{:keys [foo_id bar_id flag_present]} args]
   ...))

orestis 2019-04-04T12:01:19.017300Z

All these keys correspond 1-1 to my graphql schema definition. I’d like to have some warm fuzzy feeling that the computer made sure these keys actually exist in that schema and I didn’t mistype anything.

domkm 2019-04-04T12:01:42.017400Z

@orestis I don't know of a macro to do this but it wouldn't surprise me if someone had written one to introspect the keys of a map spec and destructure for that

domkm 2019-04-04T12:05:53.020400Z

Alternatively, it kind of sounds like you want a combination of destructure+assert so as to fail fast if the data doesn't match up with the destructure keys. Destructuring in Clojure is now implemented with spec, so you might be able to borrow that spec and implement your own let. Maybe something like assert-let where it verifies that all destructured keys on the left side exist in data on the right side.

orestis 2019-04-04T12:07:01.021300Z

Good pointer! However I’d like to validate against the GraphQL schema, not the data on the right side (as these might be nil/missing anyway since arguments can be optional).

orestis 2019-04-04T12:07:47.021400Z

D E C E P T I O N 😄

3Jane 2019-04-04T12:14:25.023Z

because trust!

3Jane 2019-04-04T12:14:54.023500Z

(I love how the guy is a new meme, but includes normal people as well as internet weirdos)

domkm 2019-04-04T12:16:09.024500Z

I would hope, but don't know, that Lacinia would ensure that every key and value are present in input objects and that missing ones are added with nil values. If that's the case, you could validate against the data directly because Lacinia would ensure the correct shape based on the schema and you would only have to check for missing keys.

orestis 2019-04-04T13:42:00.025600Z

Oh, I wouldn’t expect this by Lacinia, but it’s a good point — if some layer above could do it then validation becomes more straightforward. I wonder what about nested stuff though — and it’s still going to be a runtime validation, whereas I’d prefer if I could do this at compile time.

orestis 2019-04-04T13:45:21.025700Z

Yeah — we got a new code with my wife from him 🙂

donaldball 2019-04-04T15:02:46.028600Z

I’m working on couple of prototypes of an internal api, where for the foreseeable future, all clients are going to be clj/cljs. I’m exploring using venia to render the graphql queries themselves so I can work with edn representations pervasively, but I wanted to pause and take stock: have other folk used graphql in an all clj environment, and liked or disliked the experience?

👍 1
2019-04-05T09:06:07.032Z

@bpiel implementing graphql/lacinia directly may be not as convenient implementing the Clojure native alternative EQL via pathom then providing an extra graphql endpoint as a bridge https://github.com/denisidoro/graffiti

2019-04-05T09:08:41.032300Z

by using eql endpoint with clojurescript client you don't need an extra layer like venia/artemis while still having graphql endpoint for non-cljs clients

2019-04-05T09:13:11.032500Z

@donaldball Graphql's cons from a Clojure perspective: 1. static typing 2. string based therefore not very composable. Also, Timothy discussed it here https://www.reddit.com/r/Clojure/comments/as16f6/transcript_of_timothy_baldridge_and_me_chatting/

bpiel 2019-04-05T10:46:06.032800Z

@myguidingstar I'll check it out. Thanks

2019-04-05T13:23:03.033100Z

i also wrote a blog post on my experiences https://juxt.pro/blog/posts/through-the-looking-graph.html

donaldball 2019-04-05T17:44:47.033400Z

@myguidingstar Thanks for the link to that conversation, it was extremely interesting.

bpiel 2019-04-04T15:14:16.028700Z

Started a new project in Jan. I've been using this fork of venia so that I can can send edn (as transit) from cljs over websocket to an internal graphql api (powered by hasura, but probably switching to lacinia soonish). I definitely prefer it over anything else I've done in the past (REST etc) https://github.com/district0x/graphql-query

donaldball 2019-04-04T15:18:44.029200Z

The wins over REST endpoints for queries seem obvious on a few fronts. I’m a bit less sure about the mutations though. Do you or anyone else have any good or bad patterns for those to share?

bpiel 2019-04-04T15:19:51.029400Z

Ah yeah, I'm actually not using graphql for mutations. Not necessarily for any good reason though.

bpiel 2019-04-04T15:21:23.029600Z

This is my first experience with graphql. I guess I just felt like I wanted to focus on the query/schema aspect first.

amar 2019-04-04T15:32:39.029800Z

I found representing queries in EDN/venia somewhat difficult to work with. Ended up using strings. I haven't found a great need for changing what fields to dynamically add/remove from a query.

orestis 2019-04-04T15:51:46.030500Z

I like being able to copy paste a query from graphiql

orestis 2019-04-04T15:52:01.031Z

Haven’t needed so far to make a dynamic query at all

donaldball 2019-04-04T16:33:26.031200Z

For my team, it’s almost certainly going to be less about the dynamism than the ability to use our editors’ structural manipulation capabilities, but those are good perspectives, thanks for sharing.

timgilbert 2019-04-04T19:35:41.031400Z

We've been using https://github.com/workframers/artemis/. We use transit-json for the serialization part. The biggest PITA is translating back and forth from namespaced keys to non-namespaced ones, IMHO, but adding a translation layer at both sides also lets you shape the data into a conventient form

steveb8n 2019-04-04T22:19:56.031800Z

I’m using Venia with re-graph for reads and mutations. I find re-graph much easier to grok than Artemis. Venia providing structural editing is a win for me too