Skip to content

Commit

Permalink
feat: add graphql-java-validation module
Browse files Browse the repository at this point in the history
  • Loading branch information
hantsy committed Sep 25, 2021
1 parent df419f9 commit cd974f7
Show file tree
Hide file tree
Showing 10 changed files with 253 additions and 0 deletions.
1 change: 1 addition & 0 deletions buildSrc/src/main/kotlin/Versions.kt
Expand Up @@ -22,6 +22,7 @@ object Versions {
const val SPRING_CLOUD_VERSION = "Hoxton.SR10"
const val GRAPHQL_JAVA = "17.3"
const val GRAPHQL_JAVA_EXTENDED_SCALARS = "17.0"
const val GRAPHQL_JAVA_EXTENDED_VALIDATION = "17.0"
const val GRAPHQL_JAVA_FEDERATION = "0.7.0"
const val JACKSON_BOM = "2.12.3"
}
23 changes: 23 additions & 0 deletions graphql-dgs-extended-validation/build.gradle.kts
@@ -0,0 +1,23 @@
/*
* Copyright 2020 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

dependencies {
api(project(":graphql-dgs"))
api("com.graphql-java:graphql-java-extended-validation")
implementation("org.springframework.boot:spring-boot-autoconfigure")

testImplementation(project(":graphql-dgs-spring-boot-starter"))
}
@@ -0,0 +1,23 @@
/*
* Copyright 2021 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.netflix.graphql.dgs.autoconfig;

import graphql.validation.rules.ValidationRules;

@FunctionalInterface
public interface ValidationRulesBuilderCustomizer {
void customize(ValidationRules.Builder builder);
}
@@ -0,0 +1,65 @@
/*
* Copyright 2021 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.netflix.graphql.dgs.autoconfig

import com.netflix.graphql.dgs.DgsComponent
import com.netflix.graphql.dgs.DgsRuntimeWiring
import graphql.schema.idl.RuntimeWiring
import graphql.validation.rules.ValidationRules
import graphql.validation.schemawiring.ValidationSchemaWiring
import org.springframework.beans.factory.ObjectProvider
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@ConditionalOnClass(graphql.validation.rules.ValidationRules::class)
@ConditionalOnProperty(
prefix = "dgs.graphql.extensions.validation",
name = ["enabled"],
havingValue = "true",
matchIfMissing = true
)
@Configuration(proxyBeanMethods = false)
open class DgsExtendedValidationAutoConfiguration {

@Bean
open fun defaultExtendedValidationRegistrar(validationRulesCustomizerProvider: ObjectProvider<ValidationRulesBuilderCustomizer>): DefaultExtendedValidationRegistrar {
return DefaultExtendedValidationRegistrar(validationRulesCustomizerProvider)
}

@DgsComponent
@FunctionalInterface
fun interface ExtendedValidationRegistrar {
fun addValidationRules(builder: RuntimeWiring.Builder): RuntimeWiring.Builder
}

open class DefaultExtendedValidationRegistrar(private val validationRulesCustomizerProvider: ObjectProvider<ValidationRulesBuilderCustomizer>) :
ExtendedValidationRegistrar {

@DgsRuntimeWiring
override fun addValidationRules(builder: RuntimeWiring.Builder): RuntimeWiring.Builder {
val validationRulesBuilder = ValidationRules.newValidationRules()
validationRulesCustomizerProvider.ifAvailable { it.customize(validationRulesBuilder) }

val validationRules = validationRulesBuilder.build()
val schemaWiring = ValidationSchemaWiring(validationRules)
// we add this schema wiring to the graphql runtime
return builder.directiveWiring(schemaWiring)
}
}
}
@@ -0,0 +1,11 @@
{
"groups": [],
"properties": [
{
"name": "dgs.graphql.extensions.validation.enabled",
"type": "java.lang.Boolean",
"description": "If enabled, will provide an auto-configuration that will by default registered the Bean Validation Extensions available in graphql-java-extended-validation for the DGS Framework."
}
],
"hints": []
}
@@ -0,0 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.netflix.graphql.dgs.autoconfig.DgsExtendedValidationAutoConfiguration
@@ -0,0 +1,86 @@
/*
* Copyright 2021 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.netflix.graphql.dgs.autoconfig

import com.netflix.graphql.dgs.*
import graphql.schema.idl.SchemaParser
import graphql.schema.idl.TypeDefinitionRegistry
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.SpringBootConfiguration
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.test.context.SpringBootTest
import java.util.*

@SpringBootTest(classes = [BeanValidationSizeSmokeTest.LocalApp::class])
@EnableAutoConfiguration
internal class BeanValidationSizeSmokeTest {

@Autowired
lateinit var queryExecutor: DgsQueryExecutor

@Test
fun createPostInputValidationFailed() {
val query = "mutation newPost(\$input: CreatePostInput!){ createPost(createPostInput: \$input) }"
var variables = mapOf(
"input" to mapOf(
"title" to "test",
"content" to "test content"
)
)
val executionResult = queryExecutor.execute(query, variables)
assertThat(executionResult.errors).isNotEmpty()
}

@SpringBootConfiguration(proxyBeanMethods = false)
@SuppressWarnings("unused")
open class LocalApp {

@DgsComponent
class ExampleImplementation {

@DgsTypeDefinitionRegistry
fun typeDefinitionRegistry(): TypeDefinitionRegistry {
val schemaParser = SchemaParser()

val gqlSchema = """
| type Mutation {
| createPost(createPostInput: CreatePostInput!): String!
| }
|
| input CreatePostInput {
| title: String! @Size(min:5, max:50)
| content: String!
| }
|
| directive @Size(min : Int = 0, max : Int = 2147483647, message : String = "graphql.validation.Size.message")
| on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION
""".trimMargin()
return schemaParser.parse(gqlSchema)
}

@DgsMutation
fun createPost(@InputArgument createPostInput: CreatePostInput): String {
println(createPostInput)
return UUID.randomUUID().toString()
}
}

data class CreatePostInput(val title: String, val content: String)
}
}
@@ -0,0 +1,38 @@
/*
* Copyright 2021 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.netflix.graphql.dgs.autoconfig

import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.springframework.boot.autoconfigure.AutoConfigurations
import org.springframework.boot.test.context.runner.ApplicationContextRunner

internal class DgsExtendedValidationAutoConfigurationTests {

private val context =
ApplicationContextRunner().withConfiguration(
AutoConfigurations.of(DgsExtendedValidationAutoConfiguration::class.java)
)

@Test
fun `BeanValidation Autoconfiguration elements are available by default`() {
context.run { context ->
assertThat(context)
.hasSingleBean(DgsExtendedValidationAutoConfiguration::class.java)
}
}
}
3 changes: 3 additions & 0 deletions graphql-dgs-platform/build.gradle.kts
Expand Up @@ -51,6 +51,9 @@ dependencies {
api("com.graphql-java:graphql-java-extended-scalars") {
version { require(Versions.GRAPHQL_JAVA_EXTENDED_SCALARS) }
}
api("com.graphql-java:graphql-java-extended-validation") {
version { require(Versions.GRAPHQL_JAVA_EXTENDED_VALIDATION) }
}
api("com.apollographql.federation:federation-graphql-java-support") {
version { require(Versions.GRAPHQL_JAVA_FEDERATION) }
}
Expand Down
1 change: 1 addition & 0 deletions settings.gradle.kts
Expand Up @@ -33,6 +33,7 @@ include("graphql-dgs-spring-boot-micrometer")
include("graphql-dgs-platform")
include("graphql-dgs-platform-dependencies")
include("graphql-dgs-extended-scalars")
include("graphql-dgs-extended-validation")
include("graphql-dgs-spring-webflux-autoconfigure")
include("graphql-dgs-reactive")
include("graphql-dgs-webflux-starter")
Expand Down

0 comments on commit cd974f7

Please sign in to comment.