When using Apollo Execution plugin for server, wha...
# apollo-kotlin
j
When using Apollo Execution plugin for server, whats the correct way of injecting dependencies into it, is it to use ExecutionContext like this? https://github.com/paug/AndroidMakersBackend/blob/main/service/src/main/kotlin/androidmakers/service/Main.kt
Copy code
private fun ApplicationCall.context(uid: String?): ExecutionContext {
    return AuthenticationContext(uid) + DatastoreContext(datastore) + CacheControlContext()
}
Will I then be able to get first parameter in my class methods that using @GraphQLQuery? Or do I need some kind of singleton holding all deps? I am trying to use Ktor server DI library, but I dont mind change to something else. Trying to structure my Apollo code better.
m
Either works.
ExecutionContext
is available on each an every field/resolver, it will go down your tree.
You can also configure your
ExecutableSchemaBuilder
with a lambda for the root
Query
and
Mutation
types and pass arguments there. Those will only be available at the root
1. is more flexible 2. is more typesafe
j
Wait what configure schema builder, how would I do that?
Will it work like this if provide execution context?
Copy code
@GraphQLQuery
class Query {

    fun skills(executionContext: ExecutionContext): List<Skill> {
        return executionContext.firestore().document()
    }
}
Where I need to send in FirestoreCOntext and create extension firestore?
Also not really like this as it kind of going against using DI isch. Maybe better send in DependencyRegistry as executionContext so I can always get any dep in all query/mutation classes?
m
1.
Copy code
@GraphQLQuery
class RootQuery { 
  fun rootFields(executionContext: ExeuctionContext) {
    // retrieve your context here
  }
}

// later
val executableSchema = ServiceExecutableSchemaBuilder().build()
    apolloModule(executableSchema, executionContext =  {
      MyExecutionContext(foobar)
    })
2.
Copy code
@GraphQLQuery
class RootQuery(val context: MyArguments) {
  // root field go here
}

// later
val executableSchema = ServiceExecutableSchemaBuilder().build()
      .queryRoot {
        RootQuery(myArguments)
      }
      .build()
ExecutionContext
works like
CoroutinesContext
, it's a
Map-ish
API
j
Ah ok so overloading queryRoot that ServiceExecutableSchemaBuilder already put? How does that work if having multiple Query classes, or can only have one?
m
You can only have one root query class
j
Yes, I did notice the key and plus operator same as CorotiteContext, nice 🙂 Just very auto magic these things hard to grasp D
m
As there can be only one GraphQL query type
j
Right, yeah I think I prefer expose the DependencyRegistry as Context, semi similar I think how Koin doing in Compose I think 😛
Not very nice doing so, but kind of fine I guess 😛
m
LGTM!
j
As only one root class should be fine performance wise doing so I guess, provide executionContext with DI tree 😛
so I guess executionContext = { DiContext(Application.dependencies) + AuthContext} etc, where can send in AuthContext into mutations in Apollo require logged in user etc.