Skip to content
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

DSL implementation of fragments #235

Merged
merged 11 commits into from Sep 12, 2021
Merged

DSL implementation of fragments #235

merged 11 commits into from Sep 12, 2021

Conversation

Cito
Copy link
Member

@Cito Cito commented Aug 26, 2021

This is my suggestion for #198

@codecov-commenter
Copy link

codecov-commenter commented Aug 26, 2021

Codecov Report

Merging #235 (7354976) into master (7236bbd) will not change coverage.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff            @@
##            master      #235   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           16        16           
  Lines         1139      1214   +75     
=========================================
+ Hits          1139      1214   +75     
Impacted Files Coverage Δ
gql/cli.py 100.00% <ø> (ø)
gql/dsl.py 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7236bbd...7354976. Read the comment docs.

@Cito Cito mentioned this pull request Aug 26, 2021
Copy link
Contributor

@chadfurman chadfurman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I read through and it looks solid to me. Working on setting up a local env to play around with it a bit -- I've not yet done any contrib work on this repo. Thank you for your time and your quick response!

@vedantpuri
Copy link

Plus one to what Chad said! We really appreciate your quick response and time on this PR!

@leszekhanusz
Copy link
Collaborator

leszekhanusz commented Aug 27, 2021

Hi @Cito, thanks for this PR.

I have some remarks:

  • shouldn't we use DSLInlineFragment instead of DSLFragment in case we want to support normal fragments in the dsl module later ?
  • DSLFragment inherits from DSLField but is not really a normal field (does not support alias or arguments). So you need to ignore the ast_field type which is not valid anymore. It would be more structured to create a new abstract class DSLSelection with the select method and have DSLField and DSLFragment inherit from it. What do you think ?

@Cito
Copy link
Member Author

Cito commented Aug 27, 2021

Hi @leszekhanusz.

  • You're right - for a really clean implementation, I think it would be best to use a DSLSelection base class with two subclasses DSLField and DSLFragment, instead of abusing the existing DSLField for fragments.
  • Not sure if the DSL should really expose different objects for inline and named fragments. The distinction could be actually left transparent to the user, e.g. the dsl_gql function could optimize automatically by using named fragments instead of inline fragments. For the users of the DSL it makes no difference, since they can create fragment objects once and reuse them anyway, without needing to explicitly create named fragments.

Sorry, I must leave it to you or others to work out the details due to lack of time. I just wanted to provide a rough idea how this can be implemented.

@leszekhanusz
Copy link
Collaborator

Sorry, I must leave it to you or others to work out the details due to lack of time. I just wanted to provide a rough idea how this can be implemented.

Ok, no worries, I'll propose something.

@chadfurman
Copy link
Contributor

I also would be interested in helping if the work isn't all done at this point

@chadfurman
Copy link
Contributor

Checking in to avoid duplicate efforts. I'm setting up my local env right now and going to read over the code in d505962 plus try and get a basic inline fragment to run + run the tests + evaluate the above comment against the commit.

@leszekhanusz
Copy link
Collaborator

@chadfurman
Now that I've started working on this, I would like to finish it. I hope you don't mind.

I am currently looking at how we could also support normal fragments into this PR.

That's when I realized that the DSLSelection class was actually used for two different purposes:

  • for elements which can be arguments of the select method (selectable elements)
  • for elements on which we can use the select method (containers)

So I decided to split it into DSLSelectable and DSLSelector.

Next I am going to introduce the FragmentSpreadNode and FragmentDefinitionNode from graphql-core AST.

@chadfurman
Copy link
Contributor

chadfurman commented Aug 28, 2021

Not a problem! Ping me if you want help on anything -- this or another ticket. For now, I'll switch tasks

Thank you for your effort and time :)

fwiw: I have my local env setup and all dev deps on the right version now w/ tests and make check all fine 😅

You have a very solid project here. Great work.

@leszekhanusz
Copy link
Collaborator

Not a problem! Ping me if you want help on anything -- this or another ticket. For now, I'll switch tasks

Thank you for your effort and time :)

fwiw: I have my local env setup and all dev deps on the right version now w/ tests and make check all fine sweat_smile

You have a very solid project here. Great work.

Thanks! If you want something to do, you could maybe check the issue #125, diving into the Appsync protocol and creating another transport AWSAppsyncTransport which inherits WebsocketsTransport.

@leszekhanusz
Copy link
Collaborator

* Not sure if the DSL should really expose different objects for inline and named fragments. The distinction could be actually left transparent to the user, e.g. the dsl_gql function could optimize automatically by using named fragments instead of inline fragments. For the users of the DSL it makes no difference, since they can create fragment objects once and reuse them anyway, without needing to explicitly create named fragments.

@Cito I tried to combine normal and inline fragments in a single class but they are really different beasts, with normal fragments which need a name and can have variables.
With my current code, if you use a DSLFragment in dsl_gql, you'll get a FragmentDefinitionNode, but if you use it as an argument of a select, then you get a FragmentSpreadNode

So now we need to know when we use a fragment as an argument in a select whether this is a normal fragment, and in this case we return a FragmentSpreadNode or whether it is an inline fragment and we return an InlineFragmentNode. If we used the same class, we could detect it somehow by checking if the fragment has a name, but it might get confusing and I think it is better that we stay explicit here.

@Cito
Copy link
Member Author

Cito commented Aug 30, 2021

with normal fragments which need a name and can have variables

But as far as I see, fragments with vars were experimental only (not part of the spec) and have now been deprecated in Graphql.js (and hence in GraphQL-core as well).

@leszekhanusz
Copy link
Collaborator

Interesting... But the main problem remains and it feels cleaner to me to keep the classes separate.
What do you think of the current state of this PR? Is this something we could agree on?

@Cito
Copy link
Member Author

Cito commented Aug 30, 2021

LGTM, it's definitely cleaner and allows more control over the generated query.

@leszekhanusz
Copy link
Collaborator

Good! I'll add some documentation and merge this PR next weekend.

@vedantpuri
Copy link

@leszekhanusz Any updates on this ?

@leszekhanusz leszekhanusz changed the title Simple implementation of DSL inline fragments DSL implementation of fragments Sep 12, 2021
@leszekhanusz leszekhanusz merged commit bd96caa into master Sep 12, 2021
@leszekhanusz leszekhanusz deleted the dsl_inline_fragments branch November 8, 2021 15:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants