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

GraphQL classes always generated even when unused #522

Open
skevy opened this issue Nov 10, 2023 · 3 comments
Open

GraphQL classes always generated even when unused #522

skevy opened this issue Nov 10, 2023 · 3 comments

Comments

@skevy
Copy link

skevy commented Nov 10, 2023

Manifold is super cool! I'm investigating it for a project to help with GraphQL code generation. We have a very large schema -- 20k types, hundreds of thousands of fields. Reading through the docs, one of the things that excited me the most about Manifold was:

By default, Manifold compiles resource types to disk as the Java compiler encounters them in your code. As a consequence, a resource that is never used in your code as a type is not compiled.

However, I pulled down the "manifold-sample-graphql-app" project to try it out, and I added a new GraphQL type and compiled. This type is completely independent from the schema, is never used in code, but in target/classes/... I still see it being generated. I tried the same exercise with a JSON file (and added the json manifold plugin), and it correctly does not generate a class unless I use it, matching the experience in the docs.

Am I missing something? Is there something about GraphQL that doesn't allow for the "selective generation" behavior?

@rsmckinney
Copy link
Member

Hi @skevy. Because graphql schemas can span multiple .gql files, the granularity of type generation is at the schema level for the GraphQL manifold. As such, all the files that comprise a single schema are gathered and processed to compile the schema type.

This is definitely a design decision on my part. I considered an alternative approach where schema components could compiled separately, but it was more convenient to package everything as one unit.

If your schema were divided into sub-schemas, you could leverage manifold's multiple schema feature using .graphqlconfig files. I've attached some javadoc that explains it a bit.

Hope this helps.

/**
 * This class reflects the <i>.graphqlconfig</i> file, which defines the scope of a GraphQL schema in terms of where
 * the .graphql resources may be located.
 * <p/>
 * When no .graphqlconfig files are present, there can be only one GraphQL schema definition and the entire module's
 * namespace is the schema's scope -- all the module's .graphql resource files are considered part of the schema's
 * scope.
 * <p/>
 * When using multiple .grpahqlconfig files, it is advisable to place them in separate, unrelated directories alongside
 * the schema files. This way, each schema is scoped to the entire directory and its subdirectories.
 * <p/>
 * Note, no two .graphqlconfig files may overlap in terms of resource scoping.
 * @see <a href="https://jimkyndemeyer.github.io/js-graphql-intellij-plugin/docs/developer-guide#setting-up-multi-schema-projects-using-graphql-config">Setting up Multi-schema Projects using graphql-config</a>
 */
class GqlScope

@skevy
Copy link
Author

skevy commented Nov 10, 2023

Ok yah this is helpful -- good to know it's a design decision. Likely, if we went through with using Manifold, we would implement our own Manifold plugin because we have a bunch of special needs in this area.

Can you point me to where in https://github.com/manifold-systems/manifold/blob/master/manifold-deps-parent/manifold-graphql/src/main/java/manifold/graphql/type/GqlManifold.java this type of decision is made? Admittedly I need to read more code but it wasn't quite clicking in my head how this was differing from the JSON plugin that did operate on a file-by-file basis.

@rsmckinney
Copy link
Member

See usage of manifold.graphql.type.GqlScope#contains(file). For example, if you have two files movies.gql and queries.gql, although they compile as separate classes, the GqlScope includes both of them in the schema as the contains method indicates.

But... I wonder if manifold can improve on this. The inflection point is really at GqlParentType#addImports() where it calls importAllOtherGqlTypes(). A smarter approach would perform static analysis on the type and only include types that are necessary. Not too sure how I would go about performing that kind of analysis. I suppose a quick/dirty way would be to configure it. For instance, a config file that loosely defines discrete groupings of files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants