diff --git a/docs/content/Reference/Type System/objects-and-interfaces.md b/docs/content/Reference/Type System/objects-and-interfaces.md index e47bac88..b05f19bf 100644 --- a/docs/content/Reference/Type System/objects-and-interfaces.md +++ b/docs/content/Reference/Type System/objects-and-interfaces.md @@ -173,23 +173,12 @@ people in the second query. That's what the `dataProperty` will solve for you. ### Setting up -Using DataLoaders requires the `DataLoaderPrepared` executor: - -```kotlin -configure { - executor = Executor.DataLoaderPrepared -} -``` - *Example* ```kotlin data class Person(val id: Int, val name: String) val people = (1..5).map { Person(it, "Name-$it") } ... -configure { - executor = Executor.DataLoaderPrepared -} query("people") { resolver { -> people } } @@ -257,13 +246,3 @@ Returns: } } ``` - -### Current known issues - -This feature can be used in production but does currently have some issues: - -1. The `useDefaultPrettyPrint` doesn't work -1. Order of fields are not guaranteed to match the order that was requested -1. Custom generic type resolvers are not supported -1. Schema stitching is not supported -1. Other than that it should work as expected diff --git a/docs/content/Reference/configuration.md b/docs/content/Reference/configuration.md index 8613a401..657cb27a 100644 --- a/docs/content/Reference/configuration.md +++ b/docs/content/Reference/configuration.md @@ -8,7 +8,6 @@ KGraphQL schema allows configuration of the following properties: | objectMapper | Schema is using Jackson ObjectMapper from this property | result of `jacksonObjectMapper()` from [jackson-kotlin-module](https://github.com/FasterXML/jackson-module-kotlin) | | acceptSingleValueAsArray | Schema accepts single argument values as singleton list | `true` | | coroutineDispatcher | Schema is using CoroutineDispatcher from this property | [CommonPool](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/CommonPool.kt) | -| executor | | [Executor.Parallel](https://github.com/aPureBase/KGraphQL/blob/master/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/Executor.kt) | | genericTypeResolver | Schema is using generic type resolver from this property | [GenericTypeResolver.DEFAULT](https://github.com/aPureBase/KGraphQL/blob/master/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/GenericTypeResolver.kt) | | wrapErrors | | `true` | | timeout | | `null` | diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 16c87250..f0ecae7e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -27,7 +27,6 @@ kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serializa jackson-core-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" } jackson-module-kotlin = { module = "com.fasterxml.jackson.module:jackson-module-kotlin", version.ref = "jackson" } aedile = { module = "com.sksamuel.aedile:aedile-core", version = "2.1.2" } -deferredJsonBuilder = { module = "com.apurebase:DeferredJsonBuilder", version = "1.0.0" } ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" } ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" } ktor-server-core = { module = "io.ktor:ktor-server-core", version.ref = "ktor" } diff --git a/kgraphql-ktor-stitched/api/kgraphql-ktor-stitched.api b/kgraphql-ktor-stitched/api/kgraphql-ktor-stitched.api index 029ce4ca..42f5ddf8 100644 --- a/kgraphql-ktor-stitched/api/kgraphql-ktor-stitched.api +++ b/kgraphql-ktor-stitched/api/kgraphql-ktor-stitched.api @@ -60,8 +60,8 @@ public final class com/apurebase/kgraphql/stitched/StitchedKGraphQL { } public final class com/apurebase/kgraphql/stitched/schema/configuration/StitchedSchemaConfiguration : com/apurebase/kgraphql/configuration/SchemaConfiguration { - public fun (ZJLcom/fasterxml/jackson/databind/ObjectMapper;ZLkotlinx/coroutines/CoroutineDispatcher;ZLcom/apurebase/kgraphql/schema/execution/Executor;Ljava/lang/Long;ZLjava/util/Map;Lcom/apurebase/kgraphql/schema/execution/GenericTypeResolver;Lcom/apurebase/kgraphql/schema/execution/ArgumentTransformer;Lcom/apurebase/kgraphql/stitched/schema/execution/RemoteRequestExecutor;Ljava/lang/String;)V - public synthetic fun (ZJLcom/fasterxml/jackson/databind/ObjectMapper;ZLkotlinx/coroutines/CoroutineDispatcher;ZLcom/apurebase/kgraphql/schema/execution/Executor;Ljava/lang/Long;ZLjava/util/Map;Lcom/apurebase/kgraphql/schema/execution/GenericTypeResolver;Lcom/apurebase/kgraphql/schema/execution/ArgumentTransformer;Lcom/apurebase/kgraphql/stitched/schema/execution/RemoteRequestExecutor;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (ZJLcom/fasterxml/jackson/databind/ObjectMapper;ZLkotlinx/coroutines/CoroutineDispatcher;ZLjava/lang/Long;ZLjava/util/Map;Lcom/apurebase/kgraphql/schema/execution/GenericTypeResolver;Lcom/apurebase/kgraphql/schema/execution/ArgumentTransformer;Lcom/apurebase/kgraphql/stitched/schema/execution/RemoteRequestExecutor;Ljava/lang/String;)V + public synthetic fun (ZJLcom/fasterxml/jackson/databind/ObjectMapper;ZLkotlinx/coroutines/CoroutineDispatcher;ZLjava/lang/Long;ZLjava/util/Map;Lcom/apurebase/kgraphql/schema/execution/GenericTypeResolver;Lcom/apurebase/kgraphql/schema/execution/ArgumentTransformer;Lcom/apurebase/kgraphql/stitched/schema/execution/RemoteRequestExecutor;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun getLocalUrl ()Ljava/lang/String; public final fun getRemoteExecutor ()Lcom/apurebase/kgraphql/stitched/schema/execution/RemoteRequestExecutor; } diff --git a/kgraphql-ktor-stitched/src/main/kotlin/com/apurebase/kgraphql/stitched/schema/configuration/StitchedSchemaConfiguration.kt b/kgraphql-ktor-stitched/src/main/kotlin/com/apurebase/kgraphql/stitched/schema/configuration/StitchedSchemaConfiguration.kt index 93b2a6cd..9ef0598c 100644 --- a/kgraphql-ktor-stitched/src/main/kotlin/com/apurebase/kgraphql/stitched/schema/configuration/StitchedSchemaConfiguration.kt +++ b/kgraphql-ktor-stitched/src/main/kotlin/com/apurebase/kgraphql/stitched/schema/configuration/StitchedSchemaConfiguration.kt @@ -3,7 +3,6 @@ package com.apurebase.kgraphql.stitched.schema.configuration import com.apurebase.kgraphql.ExperimentalAPI import com.apurebase.kgraphql.configuration.SchemaConfiguration import com.apurebase.kgraphql.schema.execution.ArgumentTransformer -import com.apurebase.kgraphql.schema.execution.Executor import com.apurebase.kgraphql.schema.execution.GenericTypeResolver import com.apurebase.kgraphql.stitched.schema.execution.RemoteRequestExecutor import com.fasterxml.jackson.databind.ObjectMapper @@ -21,7 +20,6 @@ class StitchedSchemaConfiguration( // execution coroutineDispatcher: CoroutineDispatcher, wrapErrors: Boolean, - executor: Executor, timeout: Long?, // allow schema introspection introspection: Boolean = true, @@ -37,7 +35,6 @@ class StitchedSchemaConfiguration( useDefaultPrettyPrinter, coroutineDispatcher, wrapErrors, - executor, timeout, introspection, plugins, diff --git a/kgraphql-ktor-stitched/src/main/kotlin/com/apurebase/kgraphql/stitched/schema/dsl/StitchedSchemaConfigurationDSL.kt b/kgraphql-ktor-stitched/src/main/kotlin/com/apurebase/kgraphql/stitched/schema/dsl/StitchedSchemaConfigurationDSL.kt index 080cd5ec..932cc90b 100644 --- a/kgraphql-ktor-stitched/src/main/kotlin/com/apurebase/kgraphql/stitched/schema/dsl/StitchedSchemaConfigurationDSL.kt +++ b/kgraphql-ktor-stitched/src/main/kotlin/com/apurebase/kgraphql/stitched/schema/dsl/StitchedSchemaConfigurationDSL.kt @@ -24,7 +24,6 @@ open class StitchedSchemaConfigurationDSL : SchemaConfigurationDSL() { useDefaultPrettyPrinter = useDefaultPrettyPrinter, coroutineDispatcher = coroutineDispatcher, wrapErrors = wrapErrors, - executor = executor, timeout = timeout, introspection = introspection, plugins = plugins, diff --git a/kgraphql-ktor/src/test/kotlin/com/apurebase/kgraphql/KtorConfigurationTest.kt b/kgraphql-ktor/src/test/kotlin/com/apurebase/kgraphql/KtorConfigurationTest.kt deleted file mode 100644 index 81f585e4..00000000 --- a/kgraphql-ktor/src/test/kotlin/com/apurebase/kgraphql/KtorConfigurationTest.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.apurebase.kgraphql - -import com.apurebase.kgraphql.schema.execution.Executor -import io.kotest.matchers.shouldBe -import io.ktor.server.application.install -import io.ktor.server.testing.testApplication -import org.junit.jupiter.api.Test - -class KtorConfigurationTest : KtorTest() { - - @Test - fun `default configuration should use Parallel executor`() { - var checked = false - testApplication { - application { - val config = install(GraphQL) { - schema { - query("dummy") { - resolver { -> "dummy" } - } - } - } - checked = true - config.schema.configuration.executor shouldBe Executor.Parallel - } - } - checked shouldBe true - } - - @Test - fun `update configuration`() { - var checked = false - testApplication { - application { - val config = install(GraphQL) { - executor = Executor.DataLoaderPrepared - schema { - query("dummy") { - resolver { -> "dummy" } - } - } - } - checked = true - config.schema.configuration.executor shouldBe Executor.DataLoaderPrepared - } - } - checked shouldBe true - } -} diff --git a/kgraphql/api/kgraphql.api b/kgraphql/api/kgraphql.api index 92239176..b8b20488 100644 --- a/kgraphql/api/kgraphql.api +++ b/kgraphql/api/kgraphql.api @@ -82,13 +82,12 @@ public abstract interface class com/apurebase/kgraphql/configuration/PluginConfi } public class com/apurebase/kgraphql/configuration/SchemaConfiguration { - public fun (ZJLcom/fasterxml/jackson/databind/ObjectMapper;ZLkotlinx/coroutines/CoroutineDispatcher;ZLcom/apurebase/kgraphql/schema/execution/Executor;Ljava/lang/Long;ZLjava/util/Map;Lcom/apurebase/kgraphql/schema/execution/GenericTypeResolver;Lcom/apurebase/kgraphql/schema/execution/ArgumentTransformer;)V - public synthetic fun (ZJLcom/fasterxml/jackson/databind/ObjectMapper;ZLkotlinx/coroutines/CoroutineDispatcher;ZLcom/apurebase/kgraphql/schema/execution/Executor;Ljava/lang/Long;ZLjava/util/Map;Lcom/apurebase/kgraphql/schema/execution/GenericTypeResolver;Lcom/apurebase/kgraphql/schema/execution/ArgumentTransformer;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (ZJLcom/fasterxml/jackson/databind/ObjectMapper;ZLkotlinx/coroutines/CoroutineDispatcher;ZLjava/lang/Long;ZLjava/util/Map;Lcom/apurebase/kgraphql/schema/execution/GenericTypeResolver;Lcom/apurebase/kgraphql/schema/execution/ArgumentTransformer;)V + public synthetic fun (ZJLcom/fasterxml/jackson/databind/ObjectMapper;ZLkotlinx/coroutines/CoroutineDispatcher;ZLjava/lang/Long;ZLjava/util/Map;Lcom/apurebase/kgraphql/schema/execution/GenericTypeResolver;Lcom/apurebase/kgraphql/schema/execution/ArgumentTransformer;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun get (Lkotlin/reflect/KClass;)Ljava/lang/Object; public final fun getArgumentTransformer ()Lcom/apurebase/kgraphql/schema/execution/ArgumentTransformer; public final fun getCoroutineDispatcher ()Lkotlinx/coroutines/CoroutineDispatcher; public final fun getDocumentParserCacheMaximumSize ()J - public final fun getExecutor ()Lcom/apurebase/kgraphql/schema/execution/Executor; public final fun getGenericTypeResolver ()Lcom/apurebase/kgraphql/schema/execution/GenericTypeResolver; public final fun getIntrospection ()Z public final fun getObjectMapper ()Lcom/fasterxml/jackson/databind/ObjectMapper; @@ -613,7 +612,6 @@ public class com/apurebase/kgraphql/schema/dsl/SchemaConfigurationDSL { public final fun getAcceptSingleValueAsArray ()Z public final fun getCoroutineDispatcher ()Lkotlinx/coroutines/CoroutineDispatcher; public final fun getDocumentParserCacheMaximumSize ()J - public final fun getExecutor ()Lcom/apurebase/kgraphql/schema/execution/Executor; public final fun getGenericTypeResolver ()Lcom/apurebase/kgraphql/schema/execution/GenericTypeResolver; public final fun getIntrospection ()Z public final fun getObjectMapper ()Lcom/fasterxml/jackson/databind/ObjectMapper; @@ -626,7 +624,6 @@ public class com/apurebase/kgraphql/schema/dsl/SchemaConfigurationDSL { public final fun setAcceptSingleValueAsArray (Z)V public final fun setCoroutineDispatcher (Lkotlinx/coroutines/CoroutineDispatcher;)V public final fun setDocumentParserCacheMaximumSize (J)V - public final fun setExecutor (Lcom/apurebase/kgraphql/schema/execution/Executor;)V public final fun setGenericTypeResolver (Lcom/apurebase/kgraphql/schema/execution/GenericTypeResolver;)V public final fun setIntrospection (Z)V public final fun setObjectMapper (Lcom/fasterxml/jackson/databind/ObjectMapper;)V @@ -836,19 +833,6 @@ public class com/apurebase/kgraphql/schema/execution/ArgumentTransformer { public fun transformArguments (Ljava/lang/String;Ljava/lang/Object;Ljava/util/List;Lcom/apurebase/kgraphql/schema/model/ast/ArgumentNodes;Lcom/apurebase/kgraphql/request/Variables;Lcom/apurebase/kgraphql/schema/execution/Execution;Lcom/apurebase/kgraphql/Context;Lcom/apurebase/kgraphql/schema/model/FunctionWrapper;)Ljava/util/List; } -public final class com/apurebase/kgraphql/schema/execution/DataLoaderPreparedRequestExecutor : com/apurebase/kgraphql/schema/execution/RequestExecutor { - public fun (Lcom/apurebase/kgraphql/schema/DefaultSchema;)V - public final fun getSchema ()Lcom/apurebase/kgraphql/schema/DefaultSchema; - public fun suspendExecute (Lcom/apurebase/kgraphql/schema/execution/ExecutionPlan;Lcom/apurebase/kgraphql/request/VariablesJson;Lcom/apurebase/kgraphql/Context;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; -} - -public final class com/apurebase/kgraphql/schema/execution/DataLoaderPreparedRequestExecutor$ExecutionContext { - public fun (Lcom/apurebase/kgraphql/schema/execution/DataLoaderPreparedRequestExecutor;Lcom/apurebase/kgraphql/request/Variables;Lcom/apurebase/kgraphql/Context;Ljava/util/Map;)V - public final fun getLoaders ()Ljava/util/Map; - public final fun getRequestContext ()Lcom/apurebase/kgraphql/Context; - public final fun getVariables ()Lcom/apurebase/kgraphql/request/Variables; -} - public class com/apurebase/kgraphql/schema/execution/DefaultGenericTypeResolver : com/apurebase/kgraphql/schema/execution/GenericTypeResolver { public fun ()V public fun resolveMonad (Lkotlin/reflect/KType;)Lkotlin/reflect/KType; @@ -899,14 +883,12 @@ public final class com/apurebase/kgraphql/schema/execution/Execution$Union : com public final class com/apurebase/kgraphql/schema/execution/ExecutionOptions { public fun ()V - public fun (Lcom/apurebase/kgraphql/schema/execution/Executor;Ljava/lang/Long;)V - public synthetic fun (Lcom/apurebase/kgraphql/schema/execution/Executor;Ljava/lang/Long;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun component1 ()Lcom/apurebase/kgraphql/schema/execution/Executor; - public final fun component2 ()Ljava/lang/Long; - public final fun copy (Lcom/apurebase/kgraphql/schema/execution/Executor;Ljava/lang/Long;)Lcom/apurebase/kgraphql/schema/execution/ExecutionOptions; - public static synthetic fun copy$default (Lcom/apurebase/kgraphql/schema/execution/ExecutionOptions;Lcom/apurebase/kgraphql/schema/execution/Executor;Ljava/lang/Long;ILjava/lang/Object;)Lcom/apurebase/kgraphql/schema/execution/ExecutionOptions; + public fun (Ljava/lang/Long;)V + public synthetic fun (Ljava/lang/Long;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/Long; + public final fun copy (Ljava/lang/Long;)Lcom/apurebase/kgraphql/schema/execution/ExecutionOptions; + public static synthetic fun copy$default (Lcom/apurebase/kgraphql/schema/execution/ExecutionOptions;Ljava/lang/Long;ILjava/lang/Object;)Lcom/apurebase/kgraphql/schema/execution/ExecutionOptions; public fun equals (Ljava/lang/Object;)Z - public final fun getExecutor ()Lcom/apurebase/kgraphql/schema/execution/Executor; public final fun getTimeout ()Ljava/lang/Long; public fun hashCode ()I public fun toString ()Ljava/lang/String; @@ -954,14 +936,6 @@ public final class com/apurebase/kgraphql/schema/execution/ExecutionPlan : java/ public fun toArray ([Ljava/lang/Object;)[Ljava/lang/Object; } -public final class com/apurebase/kgraphql/schema/execution/Executor : java/lang/Enum { - public static final field DataLoaderPrepared Lcom/apurebase/kgraphql/schema/execution/Executor; - public static final field Parallel Lcom/apurebase/kgraphql/schema/execution/Executor; - public static fun getEntries ()Lkotlin/enums/EnumEntries; - public static fun valueOf (Ljava/lang/String;)Lcom/apurebase/kgraphql/schema/execution/Executor; - public static fun values ()[Lcom/apurebase/kgraphql/schema/execution/Executor; -} - public abstract interface class com/apurebase/kgraphql/schema/execution/GenericTypeResolver { public static final field Companion Lcom/apurebase/kgraphql/schema/execution/GenericTypeResolver$Companion; public abstract fun resolveMonad (Lkotlin/reflect/KType;)Lkotlin/reflect/KType; @@ -986,7 +960,8 @@ public final class com/apurebase/kgraphql/schema/execution/ParallelRequestExecut } public final class com/apurebase/kgraphql/schema/execution/ParallelRequestExecutor$ExecutionContext { - public fun (Lcom/apurebase/kgraphql/schema/execution/ParallelRequestExecutor;Lcom/apurebase/kgraphql/request/Variables;Lcom/apurebase/kgraphql/Context;)V + public fun (Lcom/apurebase/kgraphql/schema/execution/ParallelRequestExecutor;Lcom/apurebase/kgraphql/request/Variables;Lcom/apurebase/kgraphql/Context;Ljava/util/Map;)V + public final fun getLoaders ()Ljava/util/Map; public final fun getRequestContext ()Lcom/apurebase/kgraphql/Context; public final fun getVariables ()Lcom/apurebase/kgraphql/request/Variables; } diff --git a/kgraphql/build.gradle.kts b/kgraphql/build.gradle.kts index b4733e5c..06b69346 100644 --- a/kgraphql/build.gradle.kts +++ b/kgraphql/build.gradle.kts @@ -37,7 +37,6 @@ dependencies { implementation(libs.jackson.core.databind) implementation(libs.jackson.module.kotlin) implementation(libs.aedile) - implementation(libs.deferredJsonBuilder) testImplementation(libs.kotest) testImplementation(libs.junit.jupiter.api) diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/configuration/SchemaConfiguration.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/configuration/SchemaConfiguration.kt index f9818d14..c53852ed 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/configuration/SchemaConfiguration.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/configuration/SchemaConfiguration.kt @@ -1,7 +1,6 @@ package com.apurebase.kgraphql.configuration import com.apurebase.kgraphql.schema.execution.ArgumentTransformer -import com.apurebase.kgraphql.schema.execution.Executor import com.apurebase.kgraphql.schema.execution.GenericTypeResolver import com.fasterxml.jackson.databind.ObjectMapper import kotlinx.coroutines.CoroutineDispatcher @@ -17,7 +16,6 @@ open class SchemaConfiguration( // execution val coroutineDispatcher: CoroutineDispatcher, val wrapErrors: Boolean, - val executor: Executor, val timeout: Long?, // allow schema introspection val introspection: Boolean = true, diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/DefaultSchema.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/DefaultSchema.kt index d316c858..9f3be6f3 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/DefaultSchema.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/DefaultSchema.kt @@ -1,17 +1,12 @@ package com.apurebase.kgraphql.schema import com.apurebase.kgraphql.Context -import com.apurebase.kgraphql.ExperimentalAPI import com.apurebase.kgraphql.ValidationException import com.apurebase.kgraphql.configuration.SchemaConfiguration import com.apurebase.kgraphql.request.Introspection import com.apurebase.kgraphql.request.Parser import com.apurebase.kgraphql.request.VariablesJson -import com.apurebase.kgraphql.schema.execution.DataLoaderPreparedRequestExecutor import com.apurebase.kgraphql.schema.execution.ExecutionOptions -import com.apurebase.kgraphql.schema.execution.Executor -import com.apurebase.kgraphql.schema.execution.Executor.DataLoaderPrepared -import com.apurebase.kgraphql.schema.execution.Executor.Parallel import com.apurebase.kgraphql.schema.execution.ParallelRequestExecutor import com.apurebase.kgraphql.schema.execution.RequestExecutor import com.apurebase.kgraphql.schema.introspection.__Schema @@ -32,13 +27,7 @@ class DefaultSchema( val OPERATION_NAME_PARAM = NameNode("operationName", null) } - private val defaultRequestExecutor: RequestExecutor = getExecutor(configuration.executor) - - @OptIn(ExperimentalAPI::class) - private fun getExecutor(executor: Executor) = when (executor) { - Parallel -> ParallelRequestExecutor(this) - DataLoaderPrepared -> DataLoaderPreparedRequestExecutor(this) - } + private val requestExecutor: RequestExecutor = ParallelRequestExecutor(this) private val requestInterpreter: RequestInterpreter = RequestInterpreter(model) @@ -59,9 +48,7 @@ class DefaultSchema( val document = Parser(request).parseDocument() - val executor = options.executor?.let(this@DefaultSchema::getExecutor) ?: defaultRequestExecutor - - executor.suspendExecute( + requestExecutor.suspendExecute( plan = requestInterpreter.createExecutionPlan(document, operationName, parsedVariables, options), variables = parsedVariables, context = context diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/SchemaConfigurationDSL.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/SchemaConfigurationDSL.kt index 5d508383..c3303863 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/SchemaConfigurationDSL.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/SchemaConfigurationDSL.kt @@ -3,7 +3,6 @@ package com.apurebase.kgraphql.schema.dsl import com.apurebase.kgraphql.configuration.PluginConfiguration import com.apurebase.kgraphql.configuration.SchemaConfiguration import com.apurebase.kgraphql.schema.execution.ArgumentTransformer -import com.apurebase.kgraphql.schema.execution.Executor import com.apurebase.kgraphql.schema.execution.GenericTypeResolver import com.fasterxml.jackson.databind.DeserializationFeature import com.fasterxml.jackson.databind.ObjectMapper @@ -20,7 +19,6 @@ open class SchemaConfigurationDSL { var acceptSingleValueAsArray: Boolean = true var coroutineDispatcher: CoroutineDispatcher = Dispatchers.Default var wrapErrors: Boolean = true - var executor: Executor = Executor.Parallel var timeout: Long? = null var introspection: Boolean = true var genericTypeResolver: GenericTypeResolver = GenericTypeResolver.DEFAULT @@ -43,7 +41,6 @@ open class SchemaConfigurationDSL { useDefaultPrettyPrinter = useDefaultPrettyPrinter, coroutineDispatcher = coroutineDispatcher, wrapErrors = wrapErrors, - executor = executor, timeout = timeout, introspection = introspection, plugins = plugins, diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/DataLoaderPreparedRequestExecutor.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/DataLoaderPreparedRequestExecutor.kt deleted file mode 100644 index bd0c9005..00000000 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/DataLoaderPreparedRequestExecutor.kt +++ /dev/null @@ -1,456 +0,0 @@ -package com.apurebase.kgraphql.schema.execution - -import com.apurebase.deferredJson.DeferredJsonMap -import com.apurebase.deferredJson.deferredJsonBuilder -import com.apurebase.kgraphql.Context -import com.apurebase.kgraphql.ExecutionException -import com.apurebase.kgraphql.ExperimentalAPI -import com.apurebase.kgraphql.GraphQLError -import com.apurebase.kgraphql.request.Variables -import com.apurebase.kgraphql.request.VariablesJson -import com.apurebase.kgraphql.schema.DefaultSchema -import com.apurebase.kgraphql.schema.introspection.TypeKind -import com.apurebase.kgraphql.schema.model.FunctionWrapper -import com.apurebase.kgraphql.schema.model.ast.ArgumentNodes -import com.apurebase.kgraphql.schema.scalar.serializeScalar -import com.apurebase.kgraphql.schema.structure.Field -import com.apurebase.kgraphql.schema.structure.InputValue -import com.apurebase.kgraphql.schema.structure.Type -import kotlinx.coroutines.CompletableDeferred -import kotlinx.coroutines.Deferred -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.job -import kotlinx.serialization.json.JsonArray -import kotlinx.serialization.json.JsonElement -import kotlinx.serialization.json.JsonNull -import kotlinx.serialization.json.JsonPrimitive -import nidomiro.kdataloader.DataLoader -import kotlin.reflect.KProperty1 - -@ExperimentalAPI -class DataLoaderPreparedRequestExecutor(val schema: DefaultSchema) : RequestExecutor { - - private val argumentsHandler = ArgumentTransformer() - - inner class ExecutionContext( - val variables: Variables, - val requestContext: Context, - val loaders: Map, DataLoader> - ) - - private suspend fun ExecutionPlan.constructLoaders(): Map, DataLoader> = - coroutineScope { - val loaders = mutableMapOf, DataLoader>() - - suspend fun Collection.look() { - forEach { ex -> - when (ex) { - is Execution.Fragment -> ex.elements.look() - is Execution.Node -> { - ex.children.look() - if (ex.field is Field.DataLoader<*, *, *>) { - loaders[ex.field] = - ex.field.loader.constructNew(coroutineContext.job) as DataLoader - } - } - } - } - } - operations.look() - loaders - } - - private suspend fun DeferredJsonMap.writeOperation( - ctx: ExecutionContext, - node: Execution.Node, - operation: FunctionWrapper - ) { - node.field.checkAccess(null, ctx.requestContext) - val result: T? = operation.invoke( - funName = node.field.name, - receiver = null, - inputValues = node.field.arguments, - args = node.arguments, - executionNode = node, - ctx = ctx - ) - - applyKeyToElement(ctx, result, node, node.field.returnType, 1) - } - - private fun Any?.toPrimitive(node: Execution.Node, returnType: Type): JsonElement = when { - this == null -> createNullNode(node, returnType.unwrapList()) - this is Collection<*> || this is Array<*> -> when (this) { - is Array<*> -> toList() - else -> this as Collection<*> - }.map { it.toPrimitive(node, returnType.unwrapList()) }.let(::JsonArray) - - this is String -> JsonPrimitive(this) - this is Int -> JsonPrimitive(this) - this is Float -> JsonPrimitive(this) - this is Double -> JsonPrimitive(this) - this is Boolean -> JsonPrimitive(this) - this is Long -> JsonPrimitive(this) - returnType.unwrapped() is Type.Enum<*> -> JsonPrimitive(toString()) - else -> error("Unexpected primitive class: $this") - } - - private suspend fun DeferredJsonMap.applyKeyToElement( - ctx: ExecutionContext, - value: T?, - node: Execution.Node, - returnType: Type, - parentCount: Long - ) { - return when { - value == null -> node.aliasOrKey toValue createNullNode(node, returnType) - value is Collection<*> || value is Array<*> -> { - if (returnType.isList()) { - val values = when (value) { - is Array<*> -> value.toList() - else -> value as Collection<*> - } - - if (node.children.isEmpty()) { - node.aliasOrKey toDeferredArray { - values.map { addValue(it.toPrimitive(node, returnType)) } - } - } else { - node.aliasOrKey toDeferredArray { - values.map { v -> - when { - v == null -> addValue(createNullNode(node, returnType.unwrapList())) - node.children.isNotEmpty() -> addDeferredObj { - this@addDeferredObj.applyObjectProperties( - ctx = ctx, - value = v, - node = node, - type = returnType.unwrapList(), - parentCount = values.size.toLong() - ) - } - - else -> error("Unknown error!") - } - } - } - } - } else { - throw ExecutionException("Invalid collection value for non-collection property", node) - } - } - - value is String -> node.aliasOrKey toValue JsonPrimitive(value) - value is Int -> node.aliasOrKey toValue JsonPrimitive(value) - value is Float -> node.aliasOrKey toValue JsonPrimitive(value) - value is Double -> node.aliasOrKey toValue JsonPrimitive(value) - value is Boolean -> node.aliasOrKey toValue JsonPrimitive(value) - value is Long -> node.aliasOrKey toValue JsonPrimitive(value) - value is Short -> node.aliasOrKey toValue JsonPrimitive(value) - value is Deferred<*> -> { - deferredLaunch { - applyKeyToElement(ctx, value.await(), node, returnType, parentCount) - } - } - - node.children.isNotEmpty() -> node.aliasOrKey toDeferredObj { - applyObjectProperties(ctx, value, node, returnType, parentCount) - } - - node is Execution.Union -> node.aliasOrKey toDeferredObj { - applyObjectProperties(ctx, value, node.memberExecution(returnType), returnType, parentCount) - } - - else -> node.aliasOrKey toValue createSimpleValueNode(returnType, value, node) - } - } - - private fun createSimpleValueNode(returnType: Type, value: T, node: Execution.Node): JsonElement { - return when (val unwrapped = returnType.unwrapped()) { - is Type.Scalar<*> -> { - serializeScalar(unwrapped, value, node) - } - - is Type.Enum<*> -> JsonPrimitive(value.toString()) - else -> throw ExecutionException("Invalid Type: ${unwrapped.name}", node) - } - } - - private suspend fun DeferredJsonMap.applyObjectProperties( - ctx: ExecutionContext, - value: T, - node: Execution.Node, - type: Type, - parentCount: Long - ) { - node.children.map { child -> - when (child) { - is Execution.Fragment -> handleFragment(ctx, value, child) - else -> applyProperty(ctx, value, child, type, parentCount) - } - } - } - - private suspend fun DeferredJsonMap.handleFragment( - ctx: ExecutionContext, - value: T, - container: Execution.Fragment - ) { - if (!shouldInclude(ctx, container)) { - return - } - - val expectedType = container.condition.onType - if (expectedType.kind == TypeKind.OBJECT || expectedType.kind == TypeKind.INTERFACE) { - if (expectedType.isInstance(value)) { - container.elements.map { child -> - when (child) { - is Execution.Fragment -> handleFragment(ctx, value, child) - else -> applyProperty(ctx, value, child, expectedType, container.elements.size.toLong()) - } - } - } - } else if (expectedType.kind == TypeKind.UNION) { - // Union types do not define any fields, so children can only be fragments, cf. - // https://spec.graphql.org/October2021/#sec-Unions - container.elements.filterIsInstance().map { - handleFragment(ctx, value, it) - } - } else { - error("fragments can be specified on object types, interfaces, and unions") - } - } - - @Suppress("UNCHECKED_CAST") - private suspend fun DeferredJsonMap.applyProperty( - ctx: ExecutionContext, - value: T, - child: Execution, - type: Type, - parentCount: Long - ) { - when (child) { - is Execution.Union -> { - val field = checkNotNull(type.unwrapped()[child.key]) { - "Execution unit ${child.key} is not contained by operation return type" - } - if (field is Field.Union<*>) { - createUnionOperationNode(ctx, value, child, field as Field.Union, parentCount) - } else { - throw ExecutionException("Unexpected non-union field for union execution node", child) - } - } - - is Execution.Node -> { - val field = checkNotNull(type.unwrapped()[child.key]) { - "Execution unit ${child.key} is not contained by operation return type" - } - createPropertyNodeAsync(ctx, value, child, field, parentCount) - } - - else -> throw UnsupportedOperationException("Whatever this is isn't supported!") - } - } - - private suspend fun DeferredJsonMap.createUnionOperationNode( - ctx: ExecutionContext, - parent: T, - node: Execution.Union, - unionProperty: Field.Union, - parentCount: Long - ) { - node.field.checkAccess(parent, ctx.requestContext) - - val operationResult: Any? = unionProperty.invoke( - funName = unionProperty.name, - receiver = parent, - inputValues = node.field.arguments, - args = node.arguments, - executionNode = node, - ctx = ctx - ) - - val possibleTypes = (unionProperty.returnType.unwrapped() as Type.Union).possibleTypes - val returnType = possibleTypes.find { it.isInstance(operationResult) } - - if (returnType == null && unionProperty.returnType.isNotNullable()) { - val expectedOneOf = possibleTypes.joinToString { it.name.toString() } - throw ExecutionException( - "Unexpected type of union property value, expected one of [$expectedOneOf] but was $operationResult", - node - ) - } - - applyKeyToElement(ctx, operationResult, node, returnType ?: unionProperty.returnType, parentCount) - } - - @Suppress("UNCHECKED_CAST") - private suspend fun DeferredJsonMap.createPropertyNodeAsync( - ctx: ExecutionContext, - parentValue: T, - node: Execution.Node, - field: Field, - parentCount: Long - ) { - node.field.checkAccess(parentValue, ctx.requestContext) - if (!shouldInclude(ctx, node)) { - return - } - - when (field) { - is Field.Kotlin<*, *> -> { - val rawValue = (field.kProperty as KProperty1).get(parentValue) - val value: Any? = field.transformation?.invoke( - funName = field.name, - receiver = rawValue, - inputValues = field.arguments, - args = node.arguments, - executionNode = node, - ctx = ctx - ) ?: rawValue - - applyKeyToElement(ctx, value, node, field.returnType, parentCount) - } - - is Field.Function<*, *> -> { - handleFunctionProperty(ctx, parentValue, node, field, parentCount) - } - - is Field.DataLoader<*, *, *> -> { - field as Field.DataLoader - handleDataPropertyAsync(ctx, parentValue, node, field, parentCount) - } - - else -> error("Unexpected field type: $field, should be Field.Kotlin, Field.Function or Field.DataLoader") - } - } - - private suspend fun DeferredJsonMap.handleDataPropertyAsync( - ctx: ExecutionContext, - parentValue: T, - node: Execution.Node, - field: Field.DataLoader, - parentCount: Long - ) { - val preparedValue = field.kql.prepare.invoke( - funName = field.name, - receiver = parentValue, - inputValues = field.arguments, - args = node.arguments, - executionNode = node, - ctx = ctx - ) // ?: TODO("Nullable prepare functions isn't supported") - - val value = ctx.loaders[field]!!.loadAsync(preparedValue) - applyKeyToElement(ctx, value, node, field.returnType, parentCount) - } - - private suspend fun DeferredJsonMap.handleFunctionProperty( - ctx: ExecutionContext, - parentValue: T, - node: Execution.Node, - field: Field.Function<*, *>, - parentCount: Long - ) { - val deferred = CompletableDeferred() - deferredLaunch { - try { - val res = field.invoke( - funName = field.name, - receiver = parentValue, - inputValues = field.arguments, - args = node.arguments, - executionNode = node, - ctx = ctx - ) - deferred.complete(res) - } catch (e: Throwable) { - deferred.completeExceptionally(e) - } - } - - applyKeyToElement(ctx, deferred, node, field.returnType, parentCount) - } - - override suspend fun suspendExecute(plan: ExecutionPlan, variables: VariablesJson, context: Context) = - coroutineScope { - val result = deferredJsonBuilder(timeout = plan.options.timeout ?: schema.configuration.timeout) { - val ctx = ExecutionContext( - Variables(variables, plan.firstOrNull { it.variables != null }?.variables), - context, - plan.constructLoaders() - ) - - "data" toDeferredObj { - plan.forEach { node -> - if (shouldInclude(ctx, node)) { - writeOperation(ctx, node, node.field as Field.Function<*, *>) - } - } - } - ctx.loaders.values.map { it.dispatch() } - } - - result.await().toString() - } - - private fun createNullNode(node: Execution.Node, returnType: Type): JsonNull = - if (returnType.kind != TypeKind.NON_NULL) { - JsonNull - } else { - throw ExecutionException("null result for non-nullable operation ${node.field.name}", node) - } - - private suspend fun shouldInclude(ctx: ExecutionContext, executionNode: Execution): Boolean { - if (executionNode.directives?.isEmpty() == true) { - return true - } - return executionNode.directives?.map { (directive, arguments) -> - directive.execution.invoke( - funName = directive.name, - inputValues = directive.arguments, - receiver = null, - args = arguments, - executionNode = executionNode, - ctx = ctx - )?.include - ?: throw ExecutionException("Illegal directive implementation returning null result", executionNode) - }?.reduce { acc, b -> acc && b } ?: true - } - - internal suspend operator fun FunctionWrapper.invoke( - funName: String, - receiver: Any?, - inputValues: List>, - args: ArgumentNodes?, - executionNode: Execution, - ctx: ExecutionContext - ): T? { - val transformedArgs = argumentsHandler.transformArguments( - funName, - receiver, - inputValues, - args, - ctx.variables, - executionNode, - ctx.requestContext, - this - ) ?: return null - - return try { - if (hasReceiver) { - invoke(receiver, *transformedArgs.toTypedArray()) - } else { - invoke(*transformedArgs.toTypedArray()) - } - } catch (e: GraphQLError) { - throw e - } catch (e: Throwable) { - if (schema.configuration.wrapErrors) { - throw ExecutionException(e.message ?: "", node = executionNode, cause = e) - } else { - throw e - } - } - } -} diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ExecutionOptions.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ExecutionOptions.kt index bfd0c7d3..f904183c 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ExecutionOptions.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ExecutionOptions.kt @@ -6,6 +6,5 @@ import com.apurebase.kgraphql.configuration.SchemaConfiguration * If fields are null it'll fallback to the default from [SchemaConfiguration]. */ data class ExecutionOptions( - val executor: Executor? = null, val timeout: Long? = null ) diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/Executor.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/Executor.kt deleted file mode 100644 index 2714461c..00000000 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/Executor.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.apurebase.kgraphql.schema.execution - -enum class Executor { - Parallel, - - /** - * **This is in experimental state** - * - * * Subscriptions are not supported - * * Ordering of object fields are not guaranteed - * * Some configuration options are not taken into account when using this executor - */ - DataLoaderPrepared -} diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ParallelRequestExecutor.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ParallelRequestExecutor.kt index cab98365..2e6fd9e9 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ParallelRequestExecutor.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ParallelRequestExecutor.kt @@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.node.JsonNodeFactory import com.fasterxml.jackson.databind.node.NullNode import com.fasterxml.jackson.databind.node.ObjectNode import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.job import nidomiro.kdataloader.DataLoader import kotlin.reflect.KProperty1 @@ -28,9 +29,32 @@ class ParallelRequestExecutor(val schema: DefaultSchema) : RequestExecutor { inner class ExecutionContext( val variables: Variables, - val requestContext: Context + val requestContext: Context, + val loaders: Map, DataLoader> ) + private suspend fun ExecutionPlan.constructLoaders(): Map, DataLoader> = + coroutineScope { + val loaders = mutableMapOf, DataLoader>() + + suspend fun Collection.look() { + forEach { execution -> + when (execution) { + is Execution.Fragment -> execution.elements.look() + is Execution.Node -> { + execution.children.look() + if (execution.field is Field.DataLoader<*, *, *>) { + loaders[execution.field] = + execution.field.loader.constructNew(coroutineContext.job) as DataLoader + } + } + } + } + } + operations.look() + loaders + } + private val argumentsHandler = schema.configuration.argumentTransformer private val jsonNodeFactory = JsonNodeFactory.instance @@ -49,9 +73,10 @@ class ParallelRequestExecutor(val schema: DefaultSchema) : RequestExecutor { coroutineScope { val root = jsonNodeFactory.objectNode() val data = root.putObject("data") + val loaders = plan.constructLoaders() val resultMap = plan.toMapAsync(dispatcher) { - val ctx = ExecutionContext(Variables(variables, it.variables), context) + val ctx = ExecutionContext(Variables(variables, it.variables), context, loaders) if (shouldInclude(ctx, it)) { writeOperation( isSubscription = plan.isSubscription, @@ -369,11 +394,7 @@ class ParallelRequestExecutor(val schema: DefaultSchema) : RequestExecutor { ctx = ctx ) - // as this isn't the DataLoaderPreparedRequestExecutor. We'll use this instant workaround instead. - val loader = field.loader.constructNew(null) as DataLoader - val value = loader.loadAsync(preparedValue) - loader.dispatch() - + val value = ctx.loaders[field]!!.loadAsync(preparedValue) return createNode(ctx, value.await(), node, field.returnType) } diff --git a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/DataLoaderTest.kt b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/DataLoaderTest.kt index 15f6c864..4b04e038 100644 --- a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/DataLoaderTest.kt +++ b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/DataLoaderTest.kt @@ -2,7 +2,6 @@ package com.apurebase.kgraphql import com.apurebase.kgraphql.schema.DefaultSchema import com.apurebase.kgraphql.schema.dsl.SchemaBuilder -import com.apurebase.kgraphql.schema.execution.Executor import io.kotest.matchers.shouldBe import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll @@ -67,7 +66,6 @@ class DataLoaderTest { val schema = defaultSchema { configure { useDefaultPrettyPrinter = true - executor = Executor.DataLoaderPrepared } query("people") { diff --git a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/integration/DataLoaderExecutionTest.kt b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/integration/DataLoaderExecutionTest.kt index 6f3e29d3..1e30cc3a 100644 --- a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/integration/DataLoaderExecutionTest.kt +++ b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/integration/DataLoaderExecutionTest.kt @@ -3,7 +3,6 @@ package com.apurebase.kgraphql.integration import com.apurebase.kgraphql.defaultSchema import com.apurebase.kgraphql.deserialize import com.apurebase.kgraphql.extract -import com.apurebase.kgraphql.schema.execution.Executor import io.kotest.matchers.collections.shouldHaveSize import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.delay @@ -22,7 +21,6 @@ class DataLoaderExecutionTest { val schema = defaultSchema { configure { - executor = Executor.DataLoaderPrepared timeout = null } diff --git a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/schema/dsl/DataLoaderPropertyDSLTest.kt b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/schema/dsl/DataLoaderPropertyDSLTest.kt index 16c28972..4edc659c 100644 --- a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/schema/dsl/DataLoaderPropertyDSLTest.kt +++ b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/schema/dsl/DataLoaderPropertyDSLTest.kt @@ -5,7 +5,6 @@ import com.apurebase.kgraphql.defaultSchema import com.apurebase.kgraphql.deserialize import com.apurebase.kgraphql.extract import com.apurebase.kgraphql.schema.SchemaBuilderTest -import com.apurebase.kgraphql.schema.execution.Executor import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldNotBe import nidomiro.kdataloader.ExecutionResult @@ -18,9 +17,6 @@ class DataLoaderPropertyDSLTest { @Test fun `prepare() should support multiple arguments`() { val schema = defaultSchema { - configure { - executor = Executor.DataLoaderPrepared - } query("parent") { resolver { -> Parent() } } @@ -54,9 +50,6 @@ class DataLoaderPropertyDSLTest { @Test fun `specifying return type explicitly allows generic data property creation`() { val schema = defaultSchema { - configure { - executor = Executor.DataLoaderPrepared - } query("scenario") { resolver { -> "dummy" } } @@ -76,13 +69,9 @@ class DataLoaderPropertyDSLTest { @Test fun `creation of data properties from a list`() { - val props = listOf(Prop(typeOf()) { 0 }, Prop(typeOf()) { "test" }) val schema = defaultSchema { - configure { - executor = Executor.DataLoaderPrepared - } query("scenario") { resolver { -> "dummy" } } diff --git a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/language/ArgumentsSpecificationTest.kt b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/language/ArgumentsSpecificationTest.kt index 6e70ca22..9ae4416c 100644 --- a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/language/ArgumentsSpecificationTest.kt +++ b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/language/ArgumentsSpecificationTest.kt @@ -6,7 +6,6 @@ import com.apurebase.kgraphql.Specification import com.apurebase.kgraphql.defaultSchema import com.apurebase.kgraphql.deserialize import com.apurebase.kgraphql.executeEqualQueries -import com.apurebase.kgraphql.schema.execution.Executor import io.kotest.matchers.shouldBe import org.junit.jupiter.api.Test import java.time.LocalDate @@ -16,11 +15,6 @@ class ArgumentsSpecificationTest { val age = 432 val schema = defaultSchema { - - configure { - executor = Executor.Parallel - } - query("actor") { resolver { -> Actor("Boguś Linda", age) } } diff --git a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/language/FragmentsSpecificationTest.kt b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/language/FragmentsSpecificationTest.kt index 48b34209..cf336b63 100644 --- a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/language/FragmentsSpecificationTest.kt +++ b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/language/FragmentsSpecificationTest.kt @@ -307,7 +307,7 @@ class FragmentsSpecificationTest { // https://github.com/aPureBase/KGraphQL/issues/197 @Test fun `executor should merge several fragment declarations and field declaration`() { - val response = testedSchema.executeBlocking(//language=graphql + val response = testedSchema.executeBlocking( """ { outer { diff --git a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/language/OperationsSpecificationTest.kt b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/language/OperationsSpecificationTest.kt index 9990ab7c..d178eaa2 100644 --- a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/language/OperationsSpecificationTest.kt +++ b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/language/OperationsSpecificationTest.kt @@ -7,7 +7,6 @@ import com.apurebase.kgraphql.executeEqualQueries import com.apurebase.kgraphql.schema.SchemaException import com.apurebase.kgraphql.schema.dsl.operations.subscribe import com.apurebase.kgraphql.schema.dsl.operations.unsubscribe -import com.apurebase.kgraphql.schema.execution.Executor import com.apurebase.kgraphql.shouldBeInstanceOf import io.kotest.assertions.throwables.shouldThrowExactly import io.kotest.matchers.shouldBe @@ -22,10 +21,7 @@ class OperationsSpecificationTest { private var subscriptionResult = "" - private fun newSchema(executor: Executor = Executor.DataLoaderPrepared) = defaultSchema { - configure { - this@configure.executor = executor - } + private fun newSchema() = defaultSchema { query("fizz") { resolver { -> "buzz" }.withArgs { } @@ -82,7 +78,7 @@ class OperationsSpecificationTest { @Test fun `handle subscription`() { - val schema = newSchema(Executor.Parallel) + val schema = newSchema() schema.executeBlocking("subscription {subscriptionActor(subscription : \"mySubscription\"){name}}") subscriptionResult = "" @@ -108,7 +104,7 @@ class OperationsSpecificationTest { @Test fun `Subscription return type must be the same as the publisher's`() { val exception = shouldThrowExactly { - newSchema(Executor.Parallel).executeBlocking("subscription {subscriptionActress(subscription : \"mySubscription\"){age}}") + newSchema().executeBlocking("subscription {subscriptionActress(subscription : \"mySubscription\"){age}}") } exception.originalError shouldBeInstanceOf SchemaException::class exception shouldHaveMessage "Subscription return type must be the same as the publisher's" diff --git a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/language/VariablesSpecificationTest.kt b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/language/VariablesSpecificationTest.kt index 0f620586..20edb430 100644 --- a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/language/VariablesSpecificationTest.kt +++ b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/language/VariablesSpecificationTest.kt @@ -10,7 +10,6 @@ import com.apurebase.kgraphql.expect import com.apurebase.kgraphql.extract import com.apurebase.kgraphql.integration.BaseSchemaTest import io.kotest.matchers.shouldBe -import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test @Specification("2.10 Variables") @@ -171,18 +170,6 @@ class VariablesSpecificationTest : BaseSchemaTest() { result.extract>("data/createActor") shouldBe mapOf("name" to "Boguś Linda", "age" to 22) } - @Test - @Disabled("I don't think this should actually be supported?") - fun `query with variables and default value pointing to another variable`() { - val result = execute( - query = "mutation(\$name: String = \"Boguś Linda\", \$age : Int = \$defaultAge, \$defaultAge : Int!) " + - "{createActor(name: \$name, age: \$age){name, age}}", - variables = "{\"defaultAge\": 22}" - ) - assertNoErrors(result) - result.extract>("data/createActor") shouldBe mapOf("name" to "Boguś Linda", "age" to 22) - } - @Test fun `fragment with variable`() { val result = execute( diff --git a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/typesystem/DirectivesSpecificationTest.kt b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/typesystem/DirectivesSpecificationTest.kt index 2fc712e1..67e95a55 100644 --- a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/typesystem/DirectivesSpecificationTest.kt +++ b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/typesystem/DirectivesSpecificationTest.kt @@ -3,8 +3,6 @@ package com.apurebase.kgraphql.specification.typesystem import com.apurebase.kgraphql.Specification import com.apurebase.kgraphql.extract import com.apurebase.kgraphql.integration.BaseSchemaTest -import com.apurebase.kgraphql.schema.execution.ExecutionOptions -import com.apurebase.kgraphql.schema.execution.Executor import io.kotest.matchers.shouldBe import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows @@ -62,86 +60,4 @@ class DirectivesSpecificationTest : BaseSchemaTest() { ) assertThrows { map.extract("data/film/year") } } - - @Test - fun `query with @include directive on field (using DataLoaderPrepared executor)`() { - val map = execute( - "{film{title, year @include(if: false)}}", - options = ExecutionOptions(executor = Executor.DataLoaderPrepared) - ) - assertThrows { map.extract("data/film/year") } - } - - @Test - fun `query with @skip directive on field (using DataLoaderPrepared executor)`() { - val map = execute( - "{film{title, year @skip(if: true)}}", - options = ExecutionOptions(executor = Executor.DataLoaderPrepared) - ) - assertThrows { map.extract("data/film/year") } - } - - @Test - fun `query with @include and @skip directive on field (using DataLoaderPrepared executor)`() { - val mapBothSkip = execute( - "{film{title, year @include(if: false) @skip(if: true)}}", - options = ExecutionOptions(executor = Executor.DataLoaderPrepared) - ) - assertThrows { mapBothSkip.extract("data/film/year") } - - val mapOnlySkip = execute( - "{film{title, year @include(if: true) @skip(if: true)}}", - options = ExecutionOptions(executor = Executor.DataLoaderPrepared) - ) - assertThrows { mapOnlySkip.extract("data/film/year") } - - val mapOnlyInclude = execute( - "{film{title, year @include(if: false) @skip(if: false)}}", - options = ExecutionOptions(executor = Executor.DataLoaderPrepared) - ) - assertThrows { mapOnlyInclude.extract("data/film/year") } - - val mapNeither = execute( - "{film{title, year @include(if: true) @skip(if: false)}}", - options = ExecutionOptions(executor = Executor.DataLoaderPrepared) - ) - mapNeither.extract("data/film/year") shouldBe 2006 - } - - @Test - fun `query with @include and @skip directive on field object (using DataLoaderPrepared executor)`() { - val mapWithSkip = execute( - "{ number(big: true), film @skip(if: true) { title } }", - options = ExecutionOptions(executor = Executor.DataLoaderPrepared) - ) - assertThrows { mapWithSkip.extract("data/film") } - - val mapWithoutSkip = execute( - "{ number(big: true), film @skip(if: false) { title } }", - options = ExecutionOptions(executor = Executor.DataLoaderPrepared) - ) - mapWithoutSkip.extract("data/film/title") shouldBe "Prestige" - - val mapWithInclude = execute( - "{ number(big: true), film @include(if: true) { title } }", - options = ExecutionOptions(executor = Executor.DataLoaderPrepared) - ) - mapWithInclude.extract("data/film/title") shouldBe "Prestige" - - val mapWithoutInclude = execute( - "{ number(big: true), film @include(if: false) { title } }", - options = ExecutionOptions(executor = Executor.DataLoaderPrepared) - ) - assertThrows { mapWithoutInclude.extract("data/film") } - } - - @Test - fun `query with @include directive on field with variable (using DataLoaderPrepared executor)`() { - val map = execute( - "query film (\$include: Boolean!) {film{title, year @include(if: \$include)}}", - "{\"include\":\"false\"}", - options = ExecutionOptions(executor = Executor.DataLoaderPrepared) - ) - assertThrows { map.extract("data/film/year") } - } } diff --git a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/typesystem/NonNullSpecificationTest.kt b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/typesystem/NonNullSpecificationTest.kt index 4da14b83..a62f362f 100644 --- a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/typesystem/NonNullSpecificationTest.kt +++ b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/typesystem/NonNullSpecificationTest.kt @@ -8,7 +8,6 @@ import com.apurebase.kgraphql.ValidationException import com.apurebase.kgraphql.deserialize import com.apurebase.kgraphql.expect import com.apurebase.kgraphql.extract -import com.apurebase.kgraphql.schema.execution.Executor import com.apurebase.kgraphql.shouldBeInstanceOf import io.kotest.assertions.throwables.shouldThrowExactly import io.kotest.matchers.shouldBe @@ -76,9 +75,6 @@ class NonNullSpecificationTest { @Test fun `null within arrays should work`() { val schema = KGraphQL.schema { - configure { - executor = Executor.DataLoaderPrepared - } query("data") { resolver { -> Type2( diff --git a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/typesystem/ObjectsSpecificationTest.kt b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/typesystem/ObjectsSpecificationTest.kt index 811b3445..3abff3cf 100644 --- a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/typesystem/ObjectsSpecificationTest.kt +++ b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/typesystem/ObjectsSpecificationTest.kt @@ -1,12 +1,10 @@ package com.apurebase.kgraphql.specification.typesystem import com.apurebase.kgraphql.Actor -import com.apurebase.kgraphql.KGraphQL +import com.apurebase.kgraphql.KGraphQL.Companion.schema import com.apurebase.kgraphql.Specification import com.apurebase.kgraphql.expect import com.apurebase.kgraphql.schema.SchemaException -import com.apurebase.kgraphql.schema.dsl.SchemaBuilder -import com.apurebase.kgraphql.schema.execution.Executor import io.kotest.matchers.ints.shouldBeGreaterThan import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldNotBe @@ -20,14 +18,6 @@ class ObjectsSpecificationTest { data class Underscore(val __field: Int, val field__: String = "") data class Type(val field: String) - // TODO: We want to have [Executor.DataLoaderPrepared] working with these tests before reaching stable release of that executor! - fun schema(executor: Executor = Executor.Parallel, block: SchemaBuilder.() -> Unit) = KGraphQL.schema { - configure { - this@configure.executor = executor - } - block() - } - @Test fun `all fields defined within an Object type must not have a name which begins with __`() { expect("Illegal name '__field'. Names starting with '__' are reserved for introspection system") { @@ -313,7 +303,7 @@ class ObjectsSpecificationTest { @Test fun `fields are conceptually ordered in the same order in which they were encountered during query execution`() { - val schema = schema { // TODO: Update this test to use the new [DataLoaderPrepared] executor! + val schema = schema { query("many") { resolver { -> ManyFields() } } type { property("name") {