-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unified definition #48
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like this change. Thanks you!
This is very nice, thanks so much! Opens up for many improvements in Could you please explain what the last function in the tuple does? I see it is called |
I agree on ppx's being tough! It took an hour or so to set up a tight iteration loop to develop on it. Here's what the tuple expands into with my test-case GraphQL query (with just a let makeVariables = (~key, ()) =>
Js.Json.object_(
[|("key", Js.Json.string(key))|]
|> Js.Array.filter(((_, value)) =>
!Js.Json.test(value, Js.Json.Null)
)
|> Js.Dict.fromArray,
);
let definition = (
parse,
ppx_printed_query,
(graphql_ppx_use_json_variables_fn, ~key, ()) =>
graphql_ppx_use_json_variables_fn(
Js.Json.object_(
[|("key", Js.Json.string(key))|]
|> Js.Array.filter(((_, value)) =>
!Js.Json.test(value, Js.Json.Null)
)
|> Js.Dict.fromArray,
),
),
); So the last item in the tuple ( The idea here is that the client (apollo, urql, etc.) can pass in a function that takes a completed variables object and does whatever (probably makes a network call), and by the magic of currying, this HoF will turn it into a labelled-argument function. Hopefully that makes sense - it took awhile to noodle through in person with @Schmavery! |
@MargaretKrutikova in case it helps, you can also think of the last function as being one that takes a function It's just a little weirder because we want to be able to pass the arguments as named arguments, so it makes the types a bit harder to read in the graphql client code. This is useful because we can write whatever logic we want the client to do with the variables, and then shove that inside the composeVariables function and get back a new function that accepts all the variables as named args and then calls our function with those variables parsed into a Js.Json.t |
This was merged quickly! Wouldn't it be better to allow for some discussion, and wait until it has the native code before releasing? We are essentially duplicating data in the tuple, basically you now have the query definition and the parse function in two places. which might have some potentially negative side effects. I think it's better to have one of these situations:
I'm also interested in how this API would work if extra things are added to the definition like a serialize function. (Will these new functions also be added in two places?). |
@jfrolich I understand your concerns. Thank you for starting a discussion. I would like to answer a few of them.
We're not duplicating let definition = (
parse,
ppx_printed_query,
(graphql_ppx_use_json_variables_fn, /* variables */) => /* output */
)
First-class modules are a quite advanced feature and harder concept to grasp. On one hand it can be a good idea to force people to learn about it but on the other hand it's harder to get started coming from JS background.
This is interesting, I would really like to pay with that. It would allow us to remove this magic: https://github.com/baransu/graphql_ppx_re/blob/master/src/bucklescript/output_bucklescript_module.re#L30 but we would lose access |
Thanks a lot for the explanation, @sgrove @Schmavery ! Is there any way we could have those changes for native too? |
Please consider adding something to the README, possibly with a migration guide. Currently that information is spread out in this comment thread and a 3rd party's repo for sample code changes. |
The tuple representation allows for much slimmer, simpler usage by clients (no need for first-class modules, functors, etc.).
Here's an example of usage before/after this PR: https://github.com/FormidableLabs/reason-urql/pull/132/files#diff-58c974b09e3cc8d4b9e0332289157a63
And the
definition
-based api applied to the other operation types: teamwalnut/rescript-urql#133 (comment)Right now this PR only provides it for bucklescript - if it looks good to you, I'll copy the implementation over to the native side as well.