https://kotlinlang.org logo
#apollo-kotlin
Title
# apollo-kotlin
a

agrosner

03/06/2023, 5:05 PM
hey, can we define schema in
debug
source sets, and then consume it in
debug
directories only and have apollo generate debug only sources? use case we want to include mock schema in our app without needing to introspect a local mock server but want to ensure it doesnt leak into production
or in this case, would we then need to use the
Copy code
apollo {
  service("service") {
    outputDirConnection {
      connectToAndroidSourceSet("demoDebug")
    }
  }
}
m

Marco Pierucci

03/06/2023, 5:06 PM
I'm using per variant schema so per build type gotta be supported as well
a

agrosner

03/06/2023, 5:06 PM
so we’d need to utilize per variant schema here. ie. define one in release and one in debug
a

agrosner

03/06/2023, 5:09 PM
ah interesting. so we’d need to copy some portion of the schema over, whether all or some
m

Marco Pierucci

03/06/2023, 5:13 PM
You could have two completely different schemas, or extend a common one, depending on your needs
a

agrosner

03/06/2023, 7:45 PM
how do you extend a common one @Marco Pierucci?
found it. nvm!
createAllAndroidVariantServices
seems to do the trick.
m

mbonnin

03/06/2023, 8:51 PM
createAllAndroidVariantServices
does work. Heads up it's running a different codegen instance for each of your variants.
I was actually thinking about deprecating this one, I'm not sure there's a good use case for it.
If your debug schema is a super set of your release schema (i.e. it's a newer version), you can do stuff like this:
Copy code
apollo {
  service("release") {
    schemaFile.set(releaseSchemaFile)
    srcDir(operationFiles)
    outputDirConnection {
      connectToAndroidSourceSet("release")
    }
  }
  service("debug") {
    schemaFile.set(debugSchemaFile)

    # Reuse the main source files
    srcDir(operationFiles)
    # And add some debug only
    srcDir(debugOnlyOperationFiles)

    outputDirConnection {
      connectToAndroidSourceSet("debug")
    }
  }
}
You could also have some release specific queries. You just have to make sure there's no overlap or D8 will complain
a

agrosner

03/06/2023, 9:23 PM
we also have another dimension of different services
meaning we have multiple services. so we’d want api1Debug and api1Release for example
what we want is:
Copy code
src / main / graphql
 -> api1
    -> schema.graphqls, operations.graphl, etc
  -> api2

src / debug / graphql
  -> api1
     -> mock_extra_schema.graphqls + schema.graphqls, operations.graphql, etc
with debug inheriting all of the stuff from api / main, including scalars etc. but providing extra schema and
extend type
on main schema for development ahead of production inclusion
how would we achieve extending it, with mechanism you mentioned above?
or does not it not work this way
m

mbonnin

03/06/2023, 9:32 PM
Processing... 😅
with debug inheriting all of the stuff from api / main, including scalars etc. but providing extra schema and
extend type
on main schema for development ahead of production inclusion
Are your api1Debug and api1Release .graphql files the same or are they different too?
if you're using the same graphql files for debug and release, it's going to simplify things quite a bunch
a

agrosner

03/06/2023, 9:34 PM
we’d want consuming modules to only need
src/debug/graphql
if theyre using any operations or fields defined from the
src/debug/graphql
of the schema module
and the generated code to exist for those operations only debug source sets
m

mbonnin

03/06/2023, 9:35 PM
Oh man, mutlimodule as well?
a

agrosner

03/06/2023, 9:35 PM
but anything in
main
generated for both debug and release (or just in normal output)
m

mbonnin

03/06/2023, 9:35 PM
multi module, multi service, multi variant 😅
a

agrosner

03/06/2023, 9:35 PM
haha yeah!! our app no no joke 😆
i think i have an idea.
Copy code
api1
debugApi1 extends api1
releaseApi1 extends api1

api2
all as service configurations. where they inherit from base
api
or whatever
and then connect the debug and release ones using the
outputDirConnection
and they share same scalars, operations, and schema in main schema. but then can define /add their own. would that even work?
m

mbonnin

03/06/2023, 9:38 PM
TBH that's quite the setup
Defining custom scalars in child modules might not work
You need a central schema module that has access to all the type definitions
a

agrosner

03/06/2023, 9:39 PM
yeah we’re doing that. 1 schema module with all scalars
in reality we only need debug specific stuff so its not leaking into release builds. but dont want to lose ability for shared fragments in our consuming modules that use debug only operations
m

mbonnin

03/06/2023, 9:40 PM
our consuming modules that use debug only operations
that use debug only fragments, right?
You can't reuse operations
a

agrosner

03/06/2023, 9:40 PM
i think itll be ok if we connect the sources from the main service
so we’re developing new schema that is considered “mock” and not deployed to production. we want to use existing types and reusable fragments from those existing types. But we only want generation of those operations to exist in debug source sets
m

mbonnin

03/06/2023, 9:49 PM
My canonical way to do this would be
Copy code
// schema/build.Gradle.kts
apollo {
  service("api1Release") {
    schemaFile.set(file("src/release/graphql/api1/schema.graphqls"))
    srcDir("src/main/graphql")
    outputDirConnection {
      connectToAndroidSourceSet("release")
    }
  }
  service("api1Debug") {
    schemaFiles.set(files("src/release/graphql/api1/schema.graphqls", "src/debug/graphql/api1/extra.graphqls"))

    srcDir("src/main/graphql")

    outputDirConnection {
      connectToAndroidSourceSet("debug")
    }
  }

  // Same for api2Release and api2Debug
}
But it's hard to tell without your complete setup, this stuff is complicated
a

agrosner

03/06/2023, 9:50 PM
ok ill try this. and see if it can get it working, and shoot back here with how I did it
thank you for the help!
m

mbonnin

03/06/2023, 9:56 PM
Sure thing!
a

agrosner

03/06/2023, 10:23 PM
oh the file not found bug for apollo used coordinates surfaced
Copy code
build/generated/usedCoordinates/apollo/api1Debug/usedCoordinates.json (No such file or directory)
i think its fixed by gradle syncing + some gradle plugin improvements ive made to our superplugin
actually can repo now. if I use configuration cache, it looks for the file not found on used coordinates. ill post the error here in a sec. then if we need a ticket
Copy code
FAILURE: Build failed with an exception.

* What went wrong:
Configuration cache state could not be cached: field '__alwaysGenerateTypesMatching__' from type 'com.apollographql.apollo3.gradle.internal.ApolloGenerateSourcesTask': error writing value of type 'org.gradle.api.internal.provider.DefaultSetProperty'
> java.io.FileNotFoundException: /**/**-graphql/build/generated/usedCoordinates/apollo/api1Debug/usedCoordinates.json (No such file or directory)
Copy code
at okio.Okio__JvmOkioKt.source(JvmOkio.kt:182)
	at okio.Okio.source(Unknown Source)
	at com.apollographql.apollo3.compiler.ApolloUsedCoordinatesKt.toUsedCoordinates(ApolloUsedCoordinates.kt:25)
	at com.apollographql.apollo3.gradle.internal.DefaultApolloExtension$registerCodeGenTask$1.invoke$lambda$15(DefaultApolloExtension.kt:741)
	at org.gradle.api.internal.provider.DefaultProvider.calculateOwnValue(DefaultProvider.java:72)
m

mbonnin

03/07/2023, 7:25 PM
What task name did you invoke for that Gradle run?
a

agrosner

03/07/2023, 7:26 PM
just trying to assemble our
app
m

mbonnin

03/07/2023, 7:27 PM
assembleDebug
?
a

agrosner

03/07/2023, 7:27 PM
but it seems any invocation of
generateApolloSources
was doing it. we have that run prior to using our wrapper tasks
yeah
m

mbonnin

03/07/2023, 7:29 PM
I would expect
assembleDebug
to run all the tasks so to populate the
usedCoordinates.json
all the time. Given that
Configuration cache state could not be cached
happens at the end of the build, it's weird that the json is not there
a

agrosner

03/07/2023, 7:29 PM
ill send a redacted log. its the beginning of the build right after configure step completes
m

mbonnin

03/07/2023, 7:29 PM
ahhhh
Makes sense, at the end of the configuration step
not the end of the build...
a

agrosner

03/07/2023, 7:32 PM
redacted build log
yeah. we’re using
Copy code
add("apollo${service.capitalized()}DebugUsedCoordinatesConsumer", project)
    add("apollo${service.capitalized()}ReleaseUsedCoordinatesConsumer", project)
not the main
apolloUsedCoordinates
configurations
removing debug / release tags does not work.
Copy code
org.gradle.api.artifacts.UnknownConfigurationException: Configuration with name 'apolloApi1UsedCoordinatesConsumer' not found.
happens even if i switch all modules to using both api services and
apolloUsedCoordinates
configuration as expected, it still results in similiar configuration time error
m

mbonnin

03/07/2023, 8:10 PM
This is on
3.7.4
, right?
It's a bit late for today but I'll try tomorrow see if I can reproduce
a

agrosner

03/07/2023, 8:16 PM
yeah on 3.7.4
no problem! our services are also connected to sourceset variants:
Copy code
service("api1Debug") {
  srcDir(...) // src/debug, src/main
  outputDirConnection {
    connectToKotlinSourceSet("debug")
  }
}
"api1Release" ^ same as above except release
"api2Debug"
"api2Release"
filed an issue to track here
m

mbonnin

03/08/2023, 1:53 PM
Thanks!
37 Views