Skip to content

Commit 2f776d4

Browse files
author
Shane Myrick
committed
BREAKING CHANGE: Change GraphQLContext from annotation to interface
Instead of using an annotation and having to remember to include it in function arguments, we can create a marker interface for the GraphQLContext which library users can implement on a class to indicate that this class is the GraphQLContext. This moves the declaration from the arguments to the class itself which I think makes it more clear. This is obviously a large breaking change to fundamental part of our library. It requires heavy documentation changes and review to take place before the 2.0 release. Please review and provided feedback on the interface package path as well
1 parent 270c0b1 commit 2f776d4

File tree

13 files changed

+38
-38
lines changed

13 files changed

+38
-38
lines changed

examples/spring/src/main/kotlin/com/expediagroup/graphql/examples/context/MyGraphQLContext.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616

1717
package com.expediagroup.graphql.examples.context
1818

19-
import com.expediagroup.graphql.annotations.GraphQLContext
19+
import com.expediagroup.graphql.execution.GraphQLContext
2020
import org.springframework.http.server.reactive.ServerHttpRequest
2121
import org.springframework.http.server.reactive.ServerHttpResponse
2222

2323
/**
2424
* Simple [GraphQLContext] that holds extra value.
2525
*/
26-
class MyGraphQLContext(val myCustomValue: String, val request: ServerHttpRequest, val response: ServerHttpResponse, var subscriptionValue: String? = null)
26+
class MyGraphQLContext(val myCustomValue: String, val request: ServerHttpRequest, val response: ServerHttpResponse, var subscriptionValue: String? = null) : GraphQLContext

examples/spring/src/main/kotlin/com/expediagroup/graphql/examples/query/ContextualQuery.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package com.expediagroup.graphql.examples.query
1818

19-
import com.expediagroup.graphql.annotations.GraphQLContext
2019
import com.expediagroup.graphql.annotations.GraphQLDescription
2120
import com.expediagroup.graphql.examples.context.MyGraphQLContext
2221
import com.expediagroup.graphql.examples.model.ContextualResponse
@@ -37,6 +36,6 @@ class ContextualQuery : Query {
3736
fun contextualQuery(
3837
@GraphQLDescription("some value that will be returned to the user")
3938
value: Int,
40-
@GraphQLContext context: MyGraphQLContext
39+
context: MyGraphQLContext
4140
): ContextualResponse = ContextualResponse(value, context.myCustomValue)
4241
}

examples/spring/src/main/kotlin/com/expediagroup/graphql/examples/subscriptions/SimpleSubscription.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package com.expediagroup.graphql.examples.subscriptions
1818

19-
import com.expediagroup.graphql.annotations.GraphQLContext
2019
import com.expediagroup.graphql.annotations.GraphQLDescription
2120
import com.expediagroup.graphql.examples.context.MyGraphQLContext
2221
import com.expediagroup.graphql.spring.operations.Subscription
@@ -62,6 +61,6 @@ class SimpleSubscription : Subscription {
6261
fun flow(): Publisher<Int> = flowOf(1, 2, 4).asPublisher()
6362

6463
@GraphQLDescription("Returns a value from the subscription context")
65-
fun subscriptionContext(@GraphQLContext myGraphQLContext: MyGraphQLContext): Publisher<String> =
64+
fun subscriptionContext(myGraphQLContext: MyGraphQLContext): Publisher<String> =
6665
flowOf(myGraphQLContext.subscriptionValue ?: "", "value 2", "value3").asPublisher()
6766
}
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019 Expedia, Inc
2+
* Copyright 2020 Expedia, Inc
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -14,9 +14,10 @@
1414
* limitations under the License.
1515
*/
1616

17-
package com.expediagroup.graphql.annotations
17+
package com.expediagroup.graphql.execution
1818

1919
/**
20-
* Mark something for the GraphQL context.
20+
* Marker interface to indicate that the implementing class should be considered
21+
* as the GraphQL context. This means the implementing class will not appear in the schema.
2122
*/
22-
annotation class GraphQLContext
23+
interface GraphQLContext

graphql-kotlin-schema-generator/src/main/kotlin/com/expediagroup/graphql/generator/extensions/kParameterExtensions.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,17 @@
1616

1717
package com.expediagroup.graphql.generator.extensions
1818

19-
import com.expediagroup.graphql.annotations.GraphQLContext
2019
import com.expediagroup.graphql.exceptions.CouldNotGetNameOfKParameterException
20+
import com.expediagroup.graphql.execution.GraphQLContext
2121
import graphql.schema.DataFetchingEnvironment
2222
import kotlin.reflect.KParameter
23-
import kotlin.reflect.full.findAnnotation
2423
import kotlin.reflect.full.isSubclassOf
2524

2625
internal fun KParameter.isInterface() = this.type.getKClass().isInterface()
2726

2827
internal fun KParameter.isList() = this.type.getKClass().isSubclassOf(List::class)
2928

30-
internal fun KParameter.isGraphQLContext() = this.findAnnotation<GraphQLContext>() != null
29+
internal fun KParameter.isGraphQLContext() = this.type.getKClass().isSubclassOf(GraphQLContext::class)
3130

3231
internal fun KParameter.isDataFetchingEnvironment() = this.type.classifier == DataFetchingEnvironment::class
3332

graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/execution/FunctionDataFetcherTest.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package com.expediagroup.graphql.execution
1818

19-
import com.expediagroup.graphql.annotations.GraphQLContext
2019
import com.expediagroup.graphql.annotations.GraphQLName
2120
import com.fasterxml.jackson.annotation.JsonProperty
2221
import graphql.GraphQLException
@@ -34,14 +33,16 @@ import kotlin.test.assertTrue
3433

3534
internal class FunctionDataFetcherTest {
3635

36+
internal class MyContext(val value: String) : GraphQLContext
37+
3738
internal class MyClass {
3839
fun print(string: String) = string
3940

4041
fun printArray(items: Array<String>) = items.joinToString(separator = ":")
4142

4243
fun printList(items: List<String>) = items.joinToString(separator = ":")
4344

44-
fun context(@GraphQLContext string: String) = string
45+
fun context(myContext: MyContext) = myContext.value
4546

4647
fun dataFetchingEnvironment(environment: DataFetchingEnvironment): String = environment.field.name
4748

@@ -95,7 +96,7 @@ internal class FunctionDataFetcherTest {
9596
fun `valid target with context`() {
9697
val dataFetcher = FunctionDataFetcher(target = MyClass(), fn = MyClass::context)
9798
val mockEnvironmet: DataFetchingEnvironment = mockk()
98-
every { mockEnvironmet.getContext<String>() } returns "foo"
99+
every { mockEnvironmet.getContext<MyContext>() } returns MyContext("foo")
99100
assertEquals(expected = "foo", actual = dataFetcher.get(mockEnvironmet))
100101
}
101102

graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/generator/extensions/KFunctionExtensionsKtTest.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616

1717
package com.expediagroup.graphql.generator.extensions
1818

19-
import com.expediagroup.graphql.annotations.GraphQLContext
2019
import com.expediagroup.graphql.annotations.GraphQLIgnore
20+
import com.expediagroup.graphql.execution.GraphQLContext
2121
import graphql.schema.DataFetchingEnvironment
2222
import org.junit.jupiter.api.Test
2323
import kotlin.test.assertEquals
@@ -39,7 +39,7 @@ internal class KFunctionExtensionsKtTest {
3939
}
4040

4141
@Test
42-
fun `getValidArguments should ignore @GraphQLContext`() {
42+
fun `getValidArguments should ignore GraphQLContext`() {
4343
val args = TestingClass::context.getValidArguments()
4444
assertEquals(expected = 1, actual = args.size)
4545
assertEquals(expected = "notContext", actual = args.first().getName())
@@ -57,7 +57,7 @@ internal class KFunctionExtensionsKtTest {
5757

5858
fun ignored(@GraphQLIgnore ignoredArg: String, notIgnored: String) = "$ignoredArg and $notIgnored"
5959

60-
fun context(@GraphQLContext contextArg: String, notContext: String) = "$contextArg and $notContext"
60+
fun context(contextArg: GraphQLContext, notContext: String) = "$contextArg and $notContext"
6161

6262
fun dataFetchingEnvironment(environment: DataFetchingEnvironment, notEnvironment: String): String = "${environment.field.name} and $notEnvironment"
6363
}

graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/generator/types/GenerateFunctionTest.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,14 @@
1616

1717
package com.expediagroup.graphql.generator.types
1818

19-
import com.expediagroup.graphql.annotations.GraphQLContext
2019
import com.expediagroup.graphql.annotations.GraphQLDescription
2120
import com.expediagroup.graphql.annotations.GraphQLDirective
2221
import com.expediagroup.graphql.annotations.GraphQLIgnore
2322
import com.expediagroup.graphql.annotations.GraphQLName
2423
import com.expediagroup.graphql.exceptions.TypeNotSupportedException
2524
import com.expediagroup.graphql.execution.FunctionDataFetcher
25+
import com.expediagroup.graphql.execution.GraphQLContext
2626
import graphql.ExceptionWhileDataFetching
27-
import graphql.Scalars
2827
import graphql.Scalars.GraphQLInt
2928
import graphql.Scalars.GraphQLString
3029
import graphql.execution.DataFetcherResult
@@ -58,6 +57,8 @@ internal class GenerateFunctionTest : TypeTestHelper() {
5857
override fun nestedReturnType(): MyImplementation = MyImplementation()
5958
}
6059

60+
internal class MyContext(val value: String) : GraphQLContext
61+
6162
@GraphQLDirective(locations = [Introspection.DirectiveLocation.FIELD_DEFINITION])
6263
internal annotation class FunctionDirective(val arg: String)
6364

@@ -73,7 +74,7 @@ internal class GenerateFunctionTest : TypeTestHelper() {
7374
@GraphQLName("renamedFunction")
7475
fun originalName(input: String) = input
7576

76-
fun context(@GraphQLContext context: String, string: String) = "$context and $string"
77+
fun context(context: MyContext, string: String) = "${context.value} and $string"
7778

7879
fun ignoredParameter(color: String, @GraphQLIgnore ignoreMe: String) = "$color and $ignoreMe"
7980

@@ -141,7 +142,7 @@ internal class GenerateFunctionTest : TypeTestHelper() {
141142
assertEquals("functionDirective", directive.name)
142143
assertEquals("happy", directive.arguments[0].value)
143144
assertEquals("arg", directive.arguments[0].name)
144-
assertEquals(GraphQLNonNull(Scalars.GraphQLString), directive.arguments[0].type)
145+
assertEquals(GraphQLNonNull(GraphQLString), directive.arguments[0].type)
145146
assertEquals(
146147
directive.validLocations()?.toSet(),
147148
setOf(Introspection.DirectiveLocation.FIELD_DEFINITION)

graphql-kotlin-spring-server/src/test/kotlin/com/expediagroup/graphql/spring/context/GraphQLContextFactoryIT.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
package com.expediagroup.graphql.spring.context
1818

19-
import com.expediagroup.graphql.annotations.GraphQLContext
19+
import com.expediagroup.graphql.execution.GraphQLContext
2020
import com.expediagroup.graphql.spring.execution.GRAPHQL_CONTEXT_FILTER_ODER
2121
import com.expediagroup.graphql.spring.execution.GraphQLContextFactory
2222
import com.expediagroup.graphql.spring.model.GraphQLRequest
@@ -86,8 +86,8 @@ class GraphQLContextFactoryIT(@Autowired private val testClient: WebTestClient)
8686
}
8787

8888
class ContextualQuery : Query {
89-
fun context(@GraphQLContext ctx: CustomContext): CustomContext = ctx
89+
fun context(ctx: CustomContext): CustomContext = ctx
9090
}
9191

92-
data class CustomContext(val first: String?, val second: String?)
92+
data class CustomContext(val first: String?, val second: String?) : GraphQLContext
9393
}

graphql-kotlin-spring-server/src/test/kotlin/com/expediagroup/graphql/spring/execution/QueryHandlerTest.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ package com.expediagroup.graphql.spring.execution
1818

1919
import com.expediagroup.graphql.SchemaGeneratorConfig
2020
import com.expediagroup.graphql.TopLevelObject
21-
import com.expediagroup.graphql.annotations.GraphQLContext
2221
import com.expediagroup.graphql.exceptions.GraphQLKotlinException
22+
import com.expediagroup.graphql.execution.GraphQLContext
2323
import com.expediagroup.graphql.spring.exception.SimpleKotlinGraphQLError
2424
import com.expediagroup.graphql.spring.model.GraphQLRequest
2525
import com.expediagroup.graphql.toSchema
@@ -153,8 +153,8 @@ class QueryHandlerTest {
153153

154154
fun alwaysThrows(): String = throw GraphQLKotlinException("JUNIT Failure")
155155

156-
fun contextualValue(@GraphQLContext context: MyContext): String = context.value ?: "default"
156+
fun contextualValue(context: MyContext): String = context.value ?: "default"
157157
}
158158

159-
data class MyContext(val value: String? = null)
159+
data class MyContext(val value: String? = null) : GraphQLContext
160160
}

graphql-kotlin-spring-server/src/test/kotlin/com/expediagroup/graphql/spring/execution/SubscriptionHandlerTest.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ package com.expediagroup.graphql.spring.execution
1818

1919
import com.expediagroup.graphql.SchemaGeneratorConfig
2020
import com.expediagroup.graphql.TopLevelObject
21-
import com.expediagroup.graphql.annotations.GraphQLContext
2221
import com.expediagroup.graphql.exceptions.GraphQLKotlinException
22+
import com.expediagroup.graphql.execution.GraphQLContext
2323
import com.expediagroup.graphql.spring.model.GraphQLRequest
2424
import com.expediagroup.graphql.toSchema
2525
import graphql.ErrorType
@@ -119,10 +119,10 @@ class SubscriptionHandlerTest {
119119

120120
fun alwaysThrows(): Flux<String> = Flux.error(GraphQLKotlinException("JUNIT subscription failure"))
121121

122-
fun contextualTicker(@GraphQLContext context: SubscriptionContext): Flux<String> = Flux.range(1, 5)
122+
fun contextualTicker(context: SubscriptionContext): Flux<String> = Flux.range(1, 5)
123123
.delayElements(Duration.ofMillis(100))
124124
.map { "${context.value}:${Random.nextInt(100)}" }
125125
}
126126

127-
data class SubscriptionContext(val value: String)
127+
data class SubscriptionContext(val value: String) : GraphQLContext
128128
}

graphql-kotlin-spring-server/src/test/kotlin/com/expediagroup/graphql/spring/execution/SubscriptionWebSocketHandlerIT.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
package com.expediagroup.graphql.spring.execution
1818

19-
import com.expediagroup.graphql.annotations.GraphQLContext
19+
import com.expediagroup.graphql.execution.GraphQLContext
2020
import com.expediagroup.graphql.spring.model.GraphQLRequest
2121
import com.expediagroup.graphql.spring.model.SubscriptionOperationMessage
2222
import com.expediagroup.graphql.spring.model.SubscriptionOperationMessage.ClientMessages.GQL_CONNECTION_INIT
@@ -196,10 +196,10 @@ class SubscriptionWebSocketHandlerIT(@LocalServerPort private var port: Int) {
196196
.delayElements(Duration.ofMillis(100))
197197
.map { Random.nextInt() }
198198

199-
fun ticker(@GraphQLContext ctx: SubscriptionContext): Flux<String> = Flux.just("${ctx.value}:${Random.nextInt()}")
199+
fun ticker(ctx: SubscriptionContext): Flux<String> = Flux.just("${ctx.value}:${Random.nextInt()}")
200200
}
201201

202-
data class SubscriptionContext(val value: String)
202+
data class SubscriptionContext(val value: String) : GraphQLContext
203203

204204
private fun SubscriptionOperationMessage.toJson() = objectMapper.writeValueAsString(this)
205205
}

graphql-kotlin-spring-server/src/test/kotlin/com/expediagroup/graphql/spring/routes/RouteConfigurationIT.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
package com.expediagroup.graphql.spring.routes
1818

19-
import com.expediagroup.graphql.annotations.GraphQLContext
19+
import com.expediagroup.graphql.execution.GraphQLContext
2020
import com.expediagroup.graphql.spring.REQUEST_PARAM_OPERATION_NAME
2121
import com.expediagroup.graphql.spring.REQUEST_PARAM_QUERY
2222
import com.expediagroup.graphql.spring.REQUEST_PARAM_VARIABLES
@@ -60,10 +60,10 @@ class RouteConfigurationIT(@Autowired private val testClient: WebTestClient) {
6060
class SimpleQuery : Query {
6161
fun hello(name: String) = "Hello $name!"
6262

63-
fun context(@GraphQLContext ctx: CustomContext) = ctx.value
63+
fun context(ctx: CustomContext) = ctx.value
6464
}
6565

66-
data class CustomContext(val value: String)
66+
data class CustomContext(val value: String) : GraphQLContext
6767

6868
@Test
6969
fun `verify SDL route`() {

0 commit comments

Comments
 (0)