Skip to content

Commit 9ddc5f5

Browse files
authored
Merge pull request #2179 from Netflix/feature/strict-mode-property
Add a dgs.graphql.strictmode.enabled property
2 parents 142ffdd + 67431f7 commit 9ddc5f5

File tree

6 files changed

+94
-1
lines changed

6 files changed

+94
-1
lines changed

graphql-dgs-spring-graphql/src/main/kotlin/com/netflix/graphql/dgs/autoconfig/DgsConfigurationProperties.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ data class DgsConfigurationProperties(
3232
val preparsedDocumentProvider: DgsPreparsedDocumentProviderConfigurationProperties =
3333
DgsPreparsedDocumentProviderConfigurationProperties(),
3434
val introspection: DgsIntrospectionConfigurationProperties = DgsIntrospectionConfigurationProperties(),
35+
val strictMode: DgsStrictModeProperties = DgsStrictModeProperties(),
3536
) {
3637
data class DgsPreparsedDocumentProviderConfigurationProperties(
3738
val enabled: Boolean = false,
@@ -45,4 +46,8 @@ data class DgsConfigurationProperties(
4546
* This property toggles that visibility. */
4647
val showSdlComments: Boolean = true,
4748
)
49+
50+
data class DgsStrictModeProperties(
51+
val enabled: Boolean = true,
52+
)
4853
}

graphql-dgs-spring-graphql/src/main/kotlin/com/netflix/graphql/dgs/springgraphql/autoconfig/DgsSpringGraphQLAutoConfiguration.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ open class DgsSpringGraphQLAutoConfiguration(
307307
schemaWiringValidationEnabled = configProps.schemaWiringValidationEnabled,
308308
enableEntityFetcherCustomScalarParsing = configProps.enableEntityFetcherCustomScalarParsing,
309309
fallbackTypeResolver = fallbackTypeResolver,
310+
enableStrictMode = configProps.strictMode.enabled,
310311
)
311312

312313
@Bean

graphql-dgs-spring-graphql/src/main/resources/META-INF/spring-configuration-metadata.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@
9696
"type": "java.lang.Boolean",
9797
"description": "Enable async dispatching in the request handling. This can reduce the number of server working threads required, but requires all filters to be async aware, and tests to handle async correctly."
9898
},
99+
{
100+
"name": "dgs.graphql.strict-mode.enabled",
101+
"defaultValue": "true",
102+
"type": "java.lang.Boolean",
103+
"description": "Enable GraphQL Java strict mode on RuntimeWiring.Builder."
104+
},
99105
{
100106
"name": "dgs.graphql.virtualthreads.enabled",
101107
"defaultValue": "false",

graphql-dgs-spring-graphql/src/test/kotlin/com/netflix/graphql/dgs/springgraphql/autoconfig/DgsSpringGraphQlAutoConfigurationTest.kt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.netflix.graphql.dgs.springgraphql.autoconfig
1818

1919
import com.netflix.graphql.dgs.DgsQueryExecutor
20+
import com.netflix.graphql.dgs.autoconfig.DgsConfigurationProperties
2021
import com.netflix.graphql.dgs.internal.DgsSchemaProvider
2122
import com.netflix.graphql.dgs.mvc.internal.method.HandlerMethodArgumentResolverAdapter
2223
import com.netflix.graphql.dgs.reactive.DgsReactiveQueryExecutor
@@ -324,4 +325,31 @@ class DgsSpringGraphQlAutoConfigurationTest {
324325
}
325326
}
326327
}
328+
329+
@Test
330+
fun loadsDefaultStrictmodeConfiguration() {
331+
ApplicationContextRunner()
332+
.withConfiguration(autoConfigurations)
333+
.run { context ->
334+
assertThat(
335+
context
336+
.getBean(DgsConfigurationProperties::class.java)
337+
.strictMode.enabled,
338+
).isTrue()
339+
}
340+
}
341+
342+
@Test
343+
fun loadsStrictmodeConfiguration() {
344+
ApplicationContextRunner()
345+
.withConfiguration(autoConfigurations)
346+
.withPropertyValues("dgs.graphql.strict-mode.enabled=false")
347+
.run { context ->
348+
assertThat(
349+
context
350+
.getBean(DgsConfigurationProperties::class.java)
351+
.strictMode.enabled,
352+
).isFalse()
353+
}
354+
}
327355
}

graphql-dgs/src/main/kotlin/com/netflix/graphql/dgs/internal/DgsSchemaProvider.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ class DgsSchemaProvider
112112
private val schemaWiringValidationEnabled: Boolean = true,
113113
private val enableEntityFetcherCustomScalarParsing: Boolean = false,
114114
private val fallbackTypeResolver: TypeResolver? = null,
115+
private val enableStrictMode: Boolean = true,
115116
) {
116117
@Suppress("UNUSED_PARAMETER")
117118
@Deprecated("The mockProviders argument is no longer supported")
@@ -230,7 +231,11 @@ class DgsSchemaProvider
230231
}
231232

232233
val runtimeWiringBuilder =
233-
RuntimeWiring.newRuntimeWiring().codeRegistry(codeRegistryBuilder).fieldVisibility(fieldVisibility)
234+
RuntimeWiring
235+
.newRuntimeWiring()
236+
.strictMode(enableStrictMode)
237+
.codeRegistry(codeRegistryBuilder)
238+
.fieldVisibility(fieldVisibility)
234239

235240
val dgsCodeRegistryBuilder =
236241
DgsCodeRegistryBuilder(dataFetcherResultProcessors, codeRegistryBuilder, applicationContext)

graphql-dgs/src/test/kotlin/com/netflix/graphql/dgs/DgsSchemaProviderTest.kt

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,11 @@ import graphql.language.TypeName
3636
import graphql.schema.DataFetcher
3737
import graphql.schema.FieldCoordinates
3838
import graphql.schema.GraphQLCodeRegistry
39+
import graphql.schema.GraphQLScalarType
3940
import graphql.schema.TypeResolver
41+
import graphql.schema.idl.RuntimeWiring
4042
import graphql.schema.idl.TypeDefinitionRegistry
43+
import graphql.schema.idl.errors.StrictModeWiringException
4144
import org.assertj.core.api.Assertions.assertThat
4245
import org.assertj.core.api.Assertions.assertThatNoException
4346
import org.junit.jupiter.api.Assertions.assertEquals
@@ -83,6 +86,7 @@ internal class DgsSchemaProviderTest {
8386
schemaWiringValidationEnabled: Boolean = true,
8487
dataFetcherResultProcessors: List<DataFetcherResultProcessor> = emptyList(),
8588
fallbackTypeResolver: TypeResolver? = null,
89+
strictMode: Boolean = true,
8690
): DgsSchemaProvider =
8791
DgsSchemaProvider(
8892
applicationContext = applicationContext,
@@ -100,6 +104,7 @@ internal class DgsSchemaProviderTest {
100104
schemaWiringValidationEnabled = schemaWiringValidationEnabled,
101105
dataFetcherResultProcessors = dataFetcherResultProcessors,
102106
fallbackTypeResolver = fallbackTypeResolver,
107+
enableStrictMode = strictMode,
103108
)
104109

105110
@DgsComponent
@@ -1343,4 +1348,47 @@ internal class DgsSchemaProviderTest {
13431348
assert(sdlCommentsInResult.isEmpty())
13441349
}
13451350
}
1351+
1352+
@Test
1353+
fun `StrictMode should fail when enabled and duplicate scalars are registered`() {
1354+
contextRunner.withBeans(DuplicateScalarWiring::class).run { context ->
1355+
val schemaProvider = schemaProvider(applicationContext = context, strictMode = true)
1356+
assertThrows<StrictModeWiringException> { schemaProvider.schema() }
1357+
}
1358+
}
1359+
1360+
@Test
1361+
fun `StrictMode should not fail when disabled and duplicate scalars are registered`() {
1362+
contextRunner.withBeans(DuplicateScalarWiring::class).run { context ->
1363+
val schemaProvider = schemaProvider(applicationContext = context, strictMode = false)
1364+
assertDoesNotThrow { schemaProvider.schema() }
1365+
}
1366+
}
1367+
1368+
@DgsComponent
1369+
class DuplicateScalarWiring {
1370+
@DgsRuntimeWiring
1371+
fun customWiring(builder: RuntimeWiring.Builder): RuntimeWiring.Builder {
1372+
builder.scalar(
1373+
GraphQLScalarType
1374+
.Builder()
1375+
.name("Test")
1376+
.coercing(LocalDateTimeScalar())
1377+
.build(),
1378+
)
1379+
return builder
1380+
}
1381+
1382+
@DgsRuntimeWiring
1383+
fun customWiring2(builder: RuntimeWiring.Builder): RuntimeWiring.Builder {
1384+
builder.scalar(
1385+
GraphQLScalarType
1386+
.Builder()
1387+
.name("Test")
1388+
.coercing(LocalDateTimeScalar())
1389+
.build(),
1390+
)
1391+
return builder
1392+
}
1393+
}
13461394
}

0 commit comments

Comments
 (0)