apollo-kotlin
apollo-kotlin copied to clipboard
`generateApolloMetadata` doesn't work inside a custom `service` declaration
Summary
For our core module, containing the schema.graphqls
file I wanted to have the following setup:
apollo {
service("public") {
packageName.set("com.my.public.package")
generateApolloMetadata.set(true)
}
service("internal") {
srcDir("src/main/graphqlinternal")
schemaFile.set(file("path/to/schema.graphqls"))
packageName.set("com.my.internal.package")
generateAsInternal.set(true)
}
}
The goal is to expose the scalars and metadata as public, but still having some internal queries & mutation in that module that wouldn't be exposed publicly.
And this would fail as metadata would not be generated so other modules depending on those metadata using apolloMetadata(project(":core"))
would fail to compile.
The workaround I found is that if I rename the public
service to service
(which is the default name) it works.
Version
3.5.0
Steps to reproduce the behavior
- If your project is open source, a link to the project is greatly appreciated: https://github.com/nabla/nabla-android/blob/main/core/build.gradle
Hi! 👋
There's a drawback to have 2 services for the same schema like this: the files are generated twice.
It would probably make more sense to have 2 modules here instead, something like:
core-schema
/ \
core-internal core-public
I think ultimately you'd like the ability to have certain operations to be generated as internal, and others public, right? Whereas currently with generateAsInternal.set(true)
it's all or nothing. We have this ticket that could be a good fit: it would give the ability to customize codegen.
Hey @BoD , thanks a lot for your answer!
There's a drawback to have 2 services for the same schema like this: the files are generated twice.
Yeah I noticed that, but it's a drawback we can live with I think.
It would probably make more sense to have 2 modules here instead,
Yeah that would the perfect solution but since we're doing a library, a new module means a new artifact to publish and we want to limit those. So for us the drawback of having the files generated twice is less of a problem compared to having 2 new artifacts to publish.
I think ultimately you'd like the ability to have certain operations to be generated as internal, and others public, right?
Yes that would be the perfect solution for us!
since we're doing a library, a new module means a new artifact to publish and we want to limit those.
Oh yes that makes perfectly sense! Especially if one of the modules is 'internal' it's probably nicer to not publish it 😅
Yes that would be the perfect solution for us!
So yeah I guess #4026 is the closest thing we have for now but it's only at the "idea" phase for now.
So yeah I guess https://github.com/apollographql/apollo-kotlin/issues/4026 is the closest thing we have for now but it's only at the "idea" phase for now.
Yeah no worries it's not a blocker for us I just wanted to pass the word because maybe the limitation of generateApolloMetadata
working only on the default service name could be documented but the perfect solution can wait.
Thanks again for your answers
For the record, generateApolloMetadata
works for all service names... BUT all services sharing the same schema have to use the same service name.
So you could also name the services "public"
in your others modules and it'd work too. This is required so that Gradle dependency resolution can "match" the metadata to the correct service in case you have several schemas in the same module.
Oh I see, makes sense indeed! Thanks for the explanation
Thinking out loud, as a possible mitigation solution, you could use packageNameFromFilePath()
and put your "internal" queries in an internal
subfolder:
src/main/graphql/com/example/PublicQuery.graphql
src/main/graphql/com/example/internal/PrivateQuery.graphql
Of course someone could still use PrivateQuery
but the "internal" in the packageName should be an indication that it's not meant for public consumption.
Closing this one as you can use 3.7.0 compiler hooks to add internal
to only some classes.
For an example of how to use compiler hooks, you can take a look at:
- The compiler-hooks integration tests
- How
internal
is added using the AddInternalCompilerHooks in the lib