Skip to content

[generator] deprecated directive cleanup #591

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019 Expedia, Inc
* Copyright 2020 Expedia, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -23,4 +23,7 @@ import org.springframework.stereotype.Component
@Component
class SimpleQuery : Query {
fun dataFromBaseApp() = "hello from base app"

@Deprecated(message = "old deprecated query", replaceWith = ReplaceWith("dataFromBaseApp"))
fun deprecatedBaseAppQuery() = "this is deprecated"
}
2 changes: 2 additions & 0 deletions examples/federation/gateway/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
/node_modules
/build
/logs

*.log
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019 Expedia, Inc
* Copyright 2020 Expedia, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -51,7 +51,7 @@ import kotlin.reflect.full.findAnnotation
* Hooks for generating federated GraphQL schema.
*/
open class FederatedSchemaGeneratorHooks(private val federatedTypeRegistry: FederatedTypeRegistry) : SchemaGeneratorHooks {
private val directiveDefinitionRegex = "(^\".+\"$[\\r\\n])?^directive @\\w+.+\$[\\r\\n]*".toRegex(setOf(RegexOption.MULTILINE, RegexOption.IGNORE_CASE))
private val directiveDefinitionRegex = "(^\".+\"$[\\r\\n])?^directive @\\w+\\(.+\\) on .+?\$[\\r\\n]*".toRegex(setOf(RegexOption.MULTILINE, RegexOption.IGNORE_CASE, RegexOption.DOT_MATCHES_ALL))
private val scalarDefinitionRegex = "(^\".+\"$[\\r\\n])?^scalar (_FieldSet|_Any)$[\\r\\n]*".toRegex(setOf(RegexOption.MULTILINE, RegexOption.IGNORE_CASE))
private val emptyQueryRegex = "^type Query \\{$\\s+^\\}$\\s+".toRegex(setOf(RegexOption.MULTILINE, RegexOption.IGNORE_CASE))
private val validator = FederatedSchemaValidator()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,6 @@ directive @extends on OBJECT | INTERFACE
"Specifies the base type field set that will be selectable by the gateway"
directive @provides(fields: _FieldSet!) on FIELD_DEFINITION

"Marks the target field/enum value as deprecated"
directive @deprecated(reason: String = "No longer supported") on FIELD_DEFINITION | ENUM_VALUE

directive @custom on SCHEMA | SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION

"Space separated list of primary keys needed to access federated object"
Expand All @@ -64,6 +61,12 @@ directive @key(fields: _FieldSet!) on OBJECT | INTERFACE
"Specifies required input field set from the base type for a resolver"
directive @requires(fields: _FieldSet!) on FIELD_DEFINITION

"Marks the field or enum value as deprecated"
directive @deprecated(
"The reason for the deprecation"
reason: String! = "No longer supported"
) on FIELD_DEFINITION | ENUM_VALUE

interface Product @extends @key(fields : "id") {
id: String! @external
reviews: [Review!]!
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019 Expedia, Inc
* Copyright 2020 Expedia, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,28 +16,14 @@

package com.expediagroup.graphql.directives

import graphql.Scalars
import graphql.introspection.Introspection
import graphql.schema.GraphQLArgument
import graphql.Directives.DeprecatedDirective
import graphql.schema.GraphQLDirective

const val DEPRECATED_DIRECTIVE_NAME = "deprecated"

private val DefaultDeprecatedArgument: GraphQLArgument = GraphQLArgument.newArgument()
.name("reason")
.type(Scalars.GraphQLString)
.defaultValue("No longer supported")
.build()

internal val DeprecatedDirective: GraphQLDirective = GraphQLDirective.newDirective()
.name(DEPRECATED_DIRECTIVE_NAME)
.description("Marks the target field/enum value as deprecated")
.argument(DefaultDeprecatedArgument)
.validLocations(Introspection.DirectiveLocation.FIELD_DEFINITION, Introspection.DirectiveLocation.ENUM_VALUE)
.build()

internal fun deprecatedDirectiveWithReason(reason: String): GraphQLDirective = DeprecatedDirective.transform { directive ->
directive.argument(DefaultDeprecatedArgument.transform { arg ->
arg.value(reason)
})
val deprecatedArgument = DeprecatedDirective.getArgument("reason").transform { argument ->
argument.value(reason)
}
directive.argument(deprecatedArgument)
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019 Expedia, Inc
* Copyright 2020 Expedia, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -18,14 +18,12 @@ package com.expediagroup.graphql.generator

import com.expediagroup.graphql.SchemaGeneratorConfig
import com.expediagroup.graphql.TopLevelObject
import com.expediagroup.graphql.directives.DeprecatedDirective
import com.expediagroup.graphql.generator.state.ClassScanner
import com.expediagroup.graphql.generator.state.TypesCache
import com.expediagroup.graphql.generator.types.generateGraphQLType
import com.expediagroup.graphql.generator.types.generateMutations
import com.expediagroup.graphql.generator.types.generateQueries
import com.expediagroup.graphql.generator.types.generateSubscriptions
import graphql.Directives
import graphql.schema.GraphQLCodeRegistry
import graphql.schema.GraphQLDirective
import graphql.schema.GraphQLSchema
Expand All @@ -48,18 +46,6 @@ open class SchemaGenerator(internal val config: SchemaGeneratorConfig) {
internal val additionalTypes = mutableSetOf<GraphQLType>()
internal val directives = ConcurrentHashMap<String, GraphQLDirective>()

init {
// NOTE: @include and @defer query directives are added by graphql-java by default
// adding them explicitly here to keep it consistent with missing deprecated directive
directives[Directives.IncludeDirective.name] = Directives.IncludeDirective
directives[Directives.SkipDirective.name] = Directives.SkipDirective

// graphql-kotlin default directives
// @deprecated directive is a built-in directive that each GraphQL server should provide bu currently it is not added by graphql-java
// see https://github.com/graphql-java/graphql-java/issues/1598
directives[DeprecatedDirective.name] = DeprecatedDirective
}

/**
* Generate a schema given a list of objects to parse for the queries, mutations, and subscriptions.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019 Expedia, Inc
* Copyright 2020 Expedia, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -269,11 +269,14 @@ class GraphQLSchemaExtensionsTest {
if: Boolean!
) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT

"Marks the target field/enum value as deprecated"
directive @deprecated(reason: String = "No longer supported") on FIELD_DEFINITION | ENUM_VALUE

directive @customDirective on FIELD_DEFINITION

"Marks the field or enum value as deprecated"
directive @deprecated(
"The reason for the deprecation"
reason: String! = "No longer supported"
) on FIELD_DEFINITION | ENUM_VALUE

type ClassWithDirective {
msg: String! @customDirective
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019 Expedia, Inc
* Copyright 2020 Expedia, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -18,12 +18,10 @@ package com.expediagroup.graphql.generator.types

import com.expediagroup.graphql.annotations.GraphQLDescription
import com.expediagroup.graphql.annotations.GraphQLDirective
import com.expediagroup.graphql.directives.DeprecatedDirective
import com.expediagroup.graphql.generator.SchemaGenerator
import com.expediagroup.graphql.generator.extensions.isTrue
import com.expediagroup.graphql.getTestSchemaConfigWithMockedDirectives
import com.expediagroup.graphql.test.utils.SimpleDirective
import graphql.Directives
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import kotlin.reflect.KClass
Expand Down Expand Up @@ -119,10 +117,6 @@ internal class GenerateDirectiveTest {
@Test
fun `directives are only added to the schema once`() {
val initialCount = basicGenerator.directives.size
assertTrue(basicGenerator.directives.containsKey(Directives.IncludeDirective.name))
assertTrue(basicGenerator.directives.containsKey(Directives.SkipDirective.name))
assertTrue(basicGenerator.directives.containsKey(DeprecatedDirective.name))

val firstInvocation = generateDirectives(basicGenerator, MyClass::simpleDirective)
assertEquals(1, firstInvocation.size)
val secondInvocation = generateDirectives(basicGenerator, MyClass::simpleDirective)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019 Expedia, Inc
* Copyright 2020 Expedia, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -80,8 +80,11 @@ class RouteConfigurationIT(@Autowired private val testClient: WebTestClient) {
if: Boolean!
) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT

"Marks the target field/enum value as deprecated"
directive @deprecated(reason: String = "No longer supported") on FIELD_DEFINITION | ENUM_VALUE
"Marks the field or enum value as deprecated"
directive @deprecated(
"The reason for the deprecation"
reason: String! = "No longer supported"
) on FIELD_DEFINITION | ENUM_VALUE

type Query {
context: String!
Expand Down