-
Notifications
You must be signed in to change notification settings - Fork 651
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
Expose the CompositeAdapter when using responseBased codegenModels #5585
Comments
Hi 👋 thanks for opening this! Is this something you could do with CompilerHooks. It's experimental so there's not much doc but there are examples in the Changelog as well as integration tests. It gives you a list of KotlinPoet |
Hey @martinbonnin thanks a lot for the tip! I'm trying the approach with the compiler hooks but, as soon as I switch the Gradle plugin from 4.0.0-beta.4
4.0.0-beta.2
am I missing something with the configuration? |
|
Wait, I read the compatibility table wrong, Gradle 8.3 is already compatible with 1.9 so that part is good. Could it be that you're running an older Gradle? |
Nope, Gradle 8.4, but I just added
I'll play a little to see if I can change the visibility of the adapters 🙂 |
Uff, it seems quite difficult to modify it so that all the |
OK I think I managed. I'm not super fluent with KotlinPoet, @martinbonnin do you think this code is ok? /**
* Change the Adapters visibility from private to public.
*
* https://github.com/apollographql/apollo-kotlin/issues/5585
*/
class ChangeAdaptersModifierToPublicHooks : DefaultApolloCompilerKotlinHooks() {
override val version = "ChangeAdaptersModifierToPublicHooks.0"
override fun postProcessFiles(files: Collection<FileInfo>): Collection<FileInfo> = files.map {
it.copy(
fileSpec = it.fileSpec
.toBuilder()
.apply {
members.replaceAll { member ->
if (member is TypeSpec) {
member.changeAdaptersModifierToPublic()
} else {
member
}
}
}
.build(),
)
}
private fun TypeSpec.changeAdaptersModifierToPublic(): TypeSpec = toBuilder()
.apply {
if (superinterfaces
.keys
.filterIsInstance<ParameterizedTypeName>()
.any { it.rawType == ClassName("com.apollographql.apollo3.api", "Adapter") }
) {
modifiers.removeIf { it == KModifier.PRIVATE }
addModifiers(KModifier.PUBLIC)
}
// Recurse on nested types
typeSpecs.replaceAll { typeSpec ->
typeSpec.changeAdaptersModifierToPublic()
}
}
.build()
} |
Yup, exactly what I had in mind 👍 |
Did you mean #5612? Yeah sure, we can close this! And the CompilerHooks solution works fine for now 👍 |
Yup, exactly 👍 Sorry for the bad copy/paste and thanks for the update 🙏 |
Hi @martinbonnin, after changing the artifact version from
I'm not sure how should I migrate it to make it work with this new version. |
Right, Documentation is here and you'll want to implement the There is an example here. In your case, it would look like so (wildly untested but it seems to compile): class MyPlugin: Plugin {
override fun kotlinOutputTransform(): Transform<KotlinOutput> {
return object : Transform<KotlinOutput> {
override fun transform(input: KotlinOutput): KotlinOutput {
return KotlinOutput(
fileSpecs = input.fileSpecs.map {
it.toBuilder()
.apply {
members.replaceAll { member ->
if (member is TypeSpec) {
member.changeAdaptersModifierToPublic()
} else {
member
}
}
}
.build()
},
codegenMetadata = input.codegenMetadata
)
}
private fun TypeSpec.changeAdaptersModifierToPublic(): TypeSpec = toBuilder()
.apply {
if (superinterfaces
.keys
.filterIsInstance<ParameterizedTypeName>()
.any { it.rawType == ClassName("com.apollographql.apollo3.api", "Adapter") }
) {
modifiers.removeIf { it == KModifier.PRIVATE }
addModifiers(KModifier.PUBLIC)
}
// Recurse on nested types
typeSpecs.replaceAll { typeSpec ->
typeSpec.changeAdaptersModifierToPublic()
}
}
.build()
}
}
} The setup is really similar to a KSP processor, using the ServiceLoader API. |
Oh nice! I'll test and report back, thank you! |
Hey awesome it works! I'll write here some instructions in case someone else needs to migrate:
@martinbonnin I take this chance to ask you another question: after we switched from a single schema to multiple schemas, the IDEA plugin stopped showing shortcuts to from the Kotlin code to the Graphql Queries/Mutations and the other way around. Do you know if this is something that is not supported yet (due to the multi schema) or is this a bug that I should report here? Or it could also be a misconfiguration on my side? apollo {
service("lama") {
srcDir("src/main/graphql/lama")
packageName.set("com.veeva.link.library.network.api.graphql.lama")
plugin(projects.apolloCompilerPlugins.adapterModifier)
generateApolloMetadata.set(true)
generateFragmentImplementations.set(true)
codegenModels.set("responseBased")
decapitalizeFields.set(true)
generateDataBuilders.set(true)
introspection {
endpointUrl.set("")
schemaFile.set(file("src/main/graphql/lama/schema.graphqls"))
headers.set(mapOf("Authorization" to "JWT ${project.extra.getOrNull<String>("lamaJwtToken")}"))
}
}
}
After moving to more than 1 schema all the [navigation shortcuts](https://www.apollographql.com/blog/announcing-the-apollo-kotlin-plugin-for-android-studio-and-intellij-idea#navigation) are gone: |
Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo Kotlin usage and allow us to serve you better. |
Mmm, CI failed and, after running locally
I'll investigate and report back. |
Hey @leinardi thanks for reporting the issue about the IDE plugin! From your latest message, I understand that your modules are not at the top level, but inside another module (named That is the reason of this issue - the Apollo projects are not detected. This is already fixed but hasn't been published yet. The fix will be available in the next release, and you can also get it in the next Weekly Snapshot (those are published on Sundays), by following the instructions here. |
Oh awesome! I'll report back in case I still experience the issue after upgrading. Regarding the |
Can you share the full stacktrace with |
Sure, here:
|
Thanks for the stacktrace, I'll dig. In the meantime, I have vague recollections of builds becoming somewhat "wrong" with an empty |
Never mind: Diktat added my company package to the plugin class changing it from Sorry for the noise 🙈 |
No worries, thanks for the follow up! |
Use case
We are migrating from the
codegenModels
experimental_operationBasedWithInterfaces
to theresponseBased
and we just realized that, differently from our oldcodegenModels
, withresponseBased
the generatedCompositeAdapter
s fordata class
es are private and we cannot invoke them.We are using the adapters because we would like to manually (de)serialize some inner classes of
Query.Data
for internal use.For example something like this:
But the issue is that
User
andCountry
are now private:With the
experimental_operationBasedWithInterfaces
the adapter forCountry
was publicly available:Describe the solution you'd like
I would like to expose the
CompositeAdapter
s for the inner class, since this will allow to take advantages of this adapters when we need to manually (de)serialize these objects to, for example, send them as parameters to the Jatpack Navigation library.EDIT
Forgot to say that we are using Apollo Kotlin v4.0.0-beta.2
The text was updated successfully, but these errors were encountered: