Skip to content

Commit 05e9668

Browse files
author
Briggs
committed
Implemented graphql-java-kickstart#8. Both @deprecated(reason: String), or an empty @deprecated, directive can be used within the schema definition and the messages will now be available when a client introspects the schema for deprecated values. The README.md has also been updated to reflect the new addition.
1 parent 2bd3d9e commit 05e9668

File tree

3 files changed

+40
-4
lines changed

3 files changed

+40
-4
lines changed

README.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ SchemaParser.newParser()
270270

271271
### GraphQL Descriptions
272272

273-
GraphQL object/field/argument descriptions can be provided by the `@doc` decorator, and are added to the generated schema:
273+
GraphQL object/field/argument descriptions can be provided by the `@doc` directive, and are added to the generated schema:
274274

275275
```graphql
276276
enum Episode @doc(d: "One of the films in the Star Wars Trilogy") {
@@ -279,3 +279,18 @@ enum Episode @doc(d: "One of the films in the Star Wars Trilogy") {
279279
JEDI @doc(d: "Released in 1983")
280280
}
281281
```
282+
### GraphQL Deprecations
283+
284+
GraphQL field/enum deprecations can be provided by the `@deprecated(reason: String)` directive, and are added to the
285+
generated schema. You can either supply a **reason** argument with a string value or not supply one and receive
286+
a "No longer supported" message when introspected:
287+
288+
```graphql
289+
enum Episode @doc(d: "One of the films in the Star Wars Trilogy") {
290+
NEWHOPE @doc(d: "Released in 1977"),
291+
EMPIRE @doc(d: "Released in 1980"),
292+
JEDI @doc(d: "Released in 1983"),
293+
FANTOM @doc(d: "Released in 1999") @deprecated(reason: "Not worth referencing"),
294+
CLONES @doc(d: "Released in 2002") @deprecated
295+
}
296+
```

src/main/kotlin/com/coxautodev/graphql/tools/SchemaParser.kt

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ import graphql.schema.TypeResolverProxy
5454
*/
5555
class SchemaParser private constructor(doc: Document, resolvers: List<GraphQLResolver<*>>, userScalars: List<GraphQLScalarType>, val dictionary: BiMap<String, Class<*>>) {
5656

57+
val DEFAULT_DEPRECATION_MESSAGE = "No longer supported"
58+
5759
class Builder(
5860
private val schemaString: StringBuilder = StringBuilder(),
5961
private val resolvers: MutableList<GraphQLResolver<*>> = mutableListOf(),
@@ -287,7 +289,12 @@ class SchemaParser private constructor(doc: Document, resolvers: List<GraphQLRes
287289
definition.enumValueDefinitions.forEach { enumDefinition ->
288290
val enumName = enumDefinition.name
289291
val enumValue = type.enumConstants.find { it.toString() == enumName } ?: throw SchemaError("Expected value for name '$enumName' in enum '${type.simpleName}' but found none!")
290-
builder.value(enumName, enumValue, getDocumentation(enumDefinition.directives))
292+
getDeprecated(enumDefinition.directives).let {
293+
when (it) {
294+
is String -> builder.value(enumName, enumValue, getDocumentation(enumDefinition.directives), it)
295+
else -> builder.value(enumName, enumValue, getDocumentation(enumDefinition.directives))
296+
}
297+
}
291298
}
292299

293300
return builder.build()
@@ -325,6 +332,7 @@ class SchemaParser private constructor(doc: Document, resolvers: List<GraphQLRes
325332
private fun createFieldDefinition(field: GraphQLFieldDefinition.Builder, fieldDefinition : FieldDefinition): GraphQLFieldDefinition.Builder {
326333
field.name(fieldDefinition.name)
327334
field.description(getDocumentation(fieldDefinition.directives))
335+
getDeprecated(fieldDefinition.directives)?.let { field.deprecate(it) }
328336
field.type(determineOutputType(fieldDefinition.type))
329337
fieldDefinition.inputValueDefinitions.forEach { argumentDefinition ->
330338
field.argument { argument ->
@@ -354,6 +362,19 @@ class SchemaParser private constructor(doc: Document, resolvers: List<GraphQLRes
354362
}?.value as StringValue?)?.value
355363
}
356364

365+
/**
366+
* Returns an optional [String] describing a deprecated field/enum.
367+
* If a deprecation directive was defined using the @deprecated directive,
368+
* then a String containing either the contents of the 'reason' argument, if present, or a default
369+
* message defined in [DEFAULT_DEPRECATION_MESSAGE] will be returned. Otherwise, [null] will be returned
370+
* indicating no deprecation directive was found within the directives list.
371+
*/
372+
private fun getDeprecated(directives: List<Directive>): String? =
373+
getDirective(directives, "deprecated")?.let { directive ->
374+
(directive.arguments.find { it.name == "reason" }?.value as? StringValue)?.value ?:
375+
DEFAULT_DEPRECATION_MESSAGE
376+
}
377+
357378
private fun getDirective(directives: List<Directive>, name: String): Directive? = directives.find {
358379
it.name == name
359380
}

src/test/kotlin/com/coxautodev/graphql/tools/EndToEndSpec.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ input ItemSearchInput {
2626
}
2727
2828
input NewItemInput {
29-
name: String!
30-
type: Type!
29+
name: String! @deprecated
30+
type: Type! @deprecated(reason: "This is a reason")
3131
}
3232
3333
enum Type {

0 commit comments

Comments
 (0)