aPureBase / KGraphQL

Pure Kotlin GraphQL implementation
https://kgraphql.io
MIT License
307 stars 59 forks source link

Allow wrapping all resolvers #219

Open Martmists-GH opened 1 year ago

Martmists-GH commented 1 year ago

In my use case, KGraphQL is resolving fields lazily using Exposed. However, even when installing a hook in the pipeline at Setup which wraps the call in a newSuspendedTransaction block, it seems the dispatcher-based design of KGraphQL ignores it. Similarly, I tried creating a custom dispatcher:

        coroutineDispatcher = object : CoroutineDispatcher() {
            override fun dispatch(context: CoroutineContext, block: Runnable) {
                Dispatchers.Default.dispatch(context) {
                    transaction(database) {
                        block.run()
                    }
                }
            }
        }

however this still raises the "No transaction in context" error.

Alternatively, would it be possible to provide a RequestExecutor which does not dispatch each field and instead iterates over each, all on the same coroutine context in which the call happens so setups like this could work?

object ExposedGraphQLPatch : Plugin<Application, Unit, Unit> {
    override val key = AttributeKey<Unit>("ExposedGraphQLPatch")

    override fun install(pipeline: Application, configure: Unit.() -> Unit) {
        pipeline.intercept(ApplicationCallPipeline.Setup) {
            if (
                call.request.httpMethod == HttpMethod.Post &&
                call.request.path() == "/graphql"
            ) {
                newSuspendedTransaction(Dispatchers.IO, Globals.database) {
                    proceed()
                }
            } else {
                proceed()
            }
        }
    }
}