Skip to content
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
8 changes: 6 additions & 2 deletions src/main/java/graphql/Directives.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@

import static graphql.Scalars.GraphQLBoolean;
import static graphql.Scalars.GraphQLString;
import static graphql.introspection.Introspection.DirectiveLocation.ARGUMENT_DEFINITION;
import static graphql.introspection.Introspection.DirectiveLocation.ENUM_VALUE;
import static graphql.introspection.Introspection.DirectiveLocation.FIELD;
import static graphql.introspection.Introspection.DirectiveLocation.FIELD_DEFINITION;
import static graphql.introspection.Introspection.DirectiveLocation.FRAGMENT_SPREAD;
import static graphql.introspection.Introspection.DirectiveLocation.INLINE_FRAGMENT;
import static graphql.introspection.Introspection.DirectiveLocation.INPUT_FIELD_DEFINITION;
import static graphql.introspection.Introspection.DirectiveLocation.SCALAR;
import static graphql.language.DirectiveLocation.newDirectiveLocation;
import static graphql.language.InputValueDefinition.newInputValueDefinition;
Expand Down Expand Up @@ -40,6 +42,8 @@ public class Directives {
.name(DEPRECATED)
.directiveLocation(newDirectiveLocation().name(FIELD_DEFINITION.name()).build())
.directiveLocation(newDirectiveLocation().name(ENUM_VALUE.name()).build())
.directiveLocation(newDirectiveLocation().name(ARGUMENT_DEFINITION.name()).build())
.directiveLocation(newDirectiveLocation().name(INPUT_FIELD_DEFINITION.name()).build())
.description(createDescription("Marks the field or enum value as deprecated"))
.inputValueDefinition(
newInputValueDefinition()
Expand Down Expand Up @@ -91,13 +95,13 @@ public class Directives {
*/
public static final GraphQLDirective DeprecatedDirective = GraphQLDirective.newDirective()
.name(DEPRECATED)
.description("Marks the field or enum value as deprecated")
.description("Marks the field, argument, input field or enum value as deprecated")
.argument(newArgument()
.name("reason")
.type(GraphQLString)
.defaultValue(NO_LONGER_SUPPORTED)
.description("The reason for the deprecation"))
.validLocations(FIELD_DEFINITION, ENUM_VALUE)
.validLocations(FIELD_DEFINITION, ENUM_VALUE, ARGUMENT_DEFINITION, INPUT_FIELD_DEFINITION)
.definition(DEPRECATED_DIRECTIVE_DEFINITION)
.build();

Expand Down
70 changes: 42 additions & 28 deletions src/main/java/graphql/introspection/Introspection.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static graphql.Assert.assertTrue;
import static graphql.Scalars.GraphQLBoolean;
Expand Down Expand Up @@ -146,19 +147,35 @@ public enum TypeKind {
.field(newFieldDefinition()
.name("defaultValue")
.type(GraphQLString))
.field(newFieldDefinition()
.name("isDeprecated")
.type(GraphQLBoolean))
.field(newFieldDefinition()
.name("deprecationReason")
.type(GraphQLString))
.build();

static {
register(__InputValue, "defaultValue", environment -> {
if (environment.getSource() instanceof GraphQLArgument) {
GraphQLArgument inputField = environment.getSource();
Object type = environment.getSource();
if (type instanceof GraphQLArgument) {
GraphQLArgument inputField = (GraphQLArgument) type;
return inputField.getDefaultValue() != null ? print(inputField.getDefaultValue(), inputField.getType()) : null;
} else if (environment.getSource() instanceof GraphQLInputObjectField) {
GraphQLInputObjectField inputField = environment.getSource();
} else if (type instanceof GraphQLInputObjectField) {
GraphQLInputObjectField inputField = (GraphQLInputObjectField) type;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just tweaked it a little bit

return inputField.getDefaultValue() != null ? print(inputField.getDefaultValue(), inputField.getType()) : null;
}
return null;
});
register(__InputValue, "isDeprecated", environment -> {
Object type = environment.getSource();
if (type instanceof GraphQLArgument) {
return ((GraphQLArgument) type).isDeprecated();
} else if (type instanceof GraphQLInputObjectField) {
return ((GraphQLInputObjectField) type).isDeprecated();
}
return null;
});
register(__InputValue, "name", nameDataFetcher);
register(__InputValue, "description", descriptionDataFetcher);
}
Expand All @@ -178,7 +195,11 @@ private static String print(Object value, GraphQLInputType type) {
.type(GraphQLString))
.field(newFieldDefinition()
.name("args")
.type(nonNull(list(nonNull(__InputValue)))))
.type(nonNull(list(nonNull(__InputValue))))
.argument(newArgument()
.name("includeDeprecated")
.type(GraphQLBoolean)
.defaultValue(false)))
.field(newFieldDefinition()
.name("type")
.type(nonNull(typeRef("__Type"))))
Expand Down Expand Up @@ -232,23 +253,16 @@ private static String print(Object value, GraphQLInputType type) {

private static final IntrospectionDataFetcher fieldsFetcher = environment -> {
Object type = environment.getSource();
Boolean includeDeprecated = environment.getArgument("includeDeprecated");
if (type instanceof GraphQLFieldsContainer) {
GraphQLFieldsContainer fieldsContainer = (GraphQLFieldsContainer) type;
Boolean includeDeprecated = environment.getArgument("includeDeprecated");
List<GraphQLFieldDefinition> fieldDefinitions = environment
.getGraphQLSchema()
.getFieldVisibility()
.getFieldDefinitions(fieldsContainer);
if (includeDeprecated) {
return fieldDefinitions;
}
List<GraphQLFieldDefinition> filtered = new ArrayList<>(fieldDefinitions);
for (GraphQLFieldDefinition fieldDefinition : fieldDefinitions) {
if (fieldDefinition.isDeprecated()) {
filtered.remove(fieldDefinition);
}
}
return filtered;
return fieldDefinitions.stream()
.filter(field -> includeDeprecated || !field.isDeprecated())
.collect(Collectors.toList());
}
return null;
};
Expand Down Expand Up @@ -281,27 +295,23 @@ private static String print(Object value, GraphQLInputType type) {
Boolean includeDeprecated = environment.getArgument("includeDeprecated");
if (type instanceof GraphQLEnumType) {
List<GraphQLEnumValueDefinition> values = ((GraphQLEnumType) type).getValues();
if (includeDeprecated) {
return values;
}
List<GraphQLEnumValueDefinition> filtered = new ArrayList<>(values);
for (GraphQLEnumValueDefinition valueDefinition : values) {
if (valueDefinition.isDeprecated()) {
filtered.remove(valueDefinition);
}
}
return filtered;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tweaked the code to use .stream()

return values.stream()
.filter(enumValue -> includeDeprecated || !enumValue.isDeprecated())
.collect(Collectors.toList());
}
return null;
};

private static final IntrospectionDataFetcher inputFieldsFetcher = environment -> {
Object type = environment.getSource();
if (type instanceof GraphQLInputObjectType) {
Boolean includeDeprecated = environment.getArgument("includeDeprecated");
GraphqlFieldVisibility fieldVisibility = environment
.getGraphQLSchema()
.getFieldVisibility();
return fieldVisibility.getFieldDefinitions((GraphQLInputObjectType) type);
return fieldVisibility.getFieldDefinitions((GraphQLInputObjectType) type)
.stream().filter(inputField -> includeDeprecated || !inputField.isDeprecated())
.collect(Collectors.toList());
}
return null;
};
Expand Down Expand Up @@ -355,7 +365,11 @@ private static String print(Object value, GraphQLInputType type) {
.defaultValue(false)))
.field(newFieldDefinition()
.name("inputFields")
.type(list(nonNull(__InputValue))))
.type(list(nonNull(__InputValue)))
.argument(newArgument()
.name("includeDeprecated")
.type(GraphQLBoolean)
.defaultValue(false)))
.field(newFieldDefinition()
.name("ofType")
.type(typeRef("__Type")))
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/graphql/introspection/IntrospectionQuery.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public interface IntrospectionQuery {
" isDeprecated\n" +
" deprecationReason\n" +
" }\n" +
" inputFields {\n" +
" inputFields(includeDeprecated: true) {\n" +
" ...InputValue\n" +
" }\n" +
" interfaces {\n" +
Expand All @@ -64,6 +64,8 @@ public interface IntrospectionQuery {
" description\n" +
" type { ...TypeRef }\n" +
" defaultValue\n" +
" isDeprecated\n" +
" deprecationReason\n" +
" }\n" +
"\n" +
//
Expand Down
23 changes: 20 additions & 3 deletions src/main/java/graphql/schema/GraphQLArgument.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public class GraphQLArgument implements GraphQLNamedSchemaElement, GraphQLInputV

private final String name;
private final String description;
private final String deprecationReason;
private final GraphQLInputType originalType;
private final Object value;
private final Object defaultValue;
Expand Down Expand Up @@ -91,10 +92,10 @@ public GraphQLArgument(String name, GraphQLInputType type) {
* @deprecated use the {@link #newArgument()} builder pattern instead, as this constructor will be made private in a future version.
*/
public GraphQLArgument(String name, String description, GraphQLInputType type, Object defaultValue, InputValueDefinition definition) {
this(name, description, type, defaultValue, null, definition, Collections.emptyList());
this(name, description, type, defaultValue, null, definition, Collections.emptyList(), null);
}

private GraphQLArgument(String name, String description, GraphQLInputType type, Object defaultValue, Object value, InputValueDefinition definition, List<GraphQLDirective> directives) {
private GraphQLArgument(String name, String description, GraphQLInputType type, Object defaultValue, Object value, InputValueDefinition definition, List<GraphQLDirective> directives, String deprecationReason) {
assertValidName(name);
assertNotNull(type, () -> "type can't be null");
this.name = name;
Expand All @@ -103,6 +104,7 @@ private GraphQLArgument(String name, String description, GraphQLInputType type,
this.defaultValue = defaultValue;
this.value = value;
this.definition = definition;
this.deprecationReason = deprecationReason;
this.directives = new DirectivesUtil.DirectivesHolder(directives);
}

Expand Down Expand Up @@ -149,6 +151,14 @@ public String getDescription() {
return description;
}

public String getDeprecationReason() {
return deprecationReason;
}

public boolean isDeprecated() {
return deprecationReason != null;
}

public InputValueDefinition getDefinition() {
return definition;
}
Expand Down Expand Up @@ -256,6 +266,7 @@ public static class Builder extends GraphqlTypeBuilder {
private GraphQLInputType type;
private Object defaultValue = DEFAULT_VALUE_SENTINEL;
private Object value;
private String deprecationReason;
private InputValueDefinition definition;
private final List<GraphQLDirective> directives = new ArrayList<>();

Expand All @@ -269,6 +280,7 @@ public Builder(GraphQLArgument existing) {
this.defaultValue = existing.defaultValue;
this.description = existing.getDescription();
this.definition = existing.getDefinition();
this.deprecationReason = existing.deprecationReason;
DirectivesUtil.enforceAddAll(this.directives, existing.getDirectives());
}

Expand All @@ -295,6 +307,10 @@ public Builder definition(InputValueDefinition definition) {
return this;
}

public Builder deprecate(String deprecationReason) {
this.deprecationReason = deprecationReason;
return this;
}

public Builder type(GraphQLInputType type) {
this.type = type;
Expand Down Expand Up @@ -356,7 +372,8 @@ public GraphQLArgument build() {
defaultValue,
value,
definition,
sort(directives, GraphQLArgument.class, GraphQLDirective.class)
sort(directives, GraphQLArgument.class, GraphQLDirective.class),
deprecationReason
);
}
}
Expand Down
29 changes: 24 additions & 5 deletions src/main/java/graphql/schema/GraphQLInputObjectField.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package graphql.schema;


import com.google.common.collect.ImmutableList;
import graphql.DirectivesUtil;
import graphql.Internal;
import graphql.PublicApi;
Expand All @@ -10,14 +9,12 @@
import graphql.util.TraverserContext;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

import static graphql.Assert.assertNotNull;
import static graphql.Assert.assertValidName;
import static graphql.util.FpKit.getByName;
import static java.util.Collections.emptyList;

/**
Expand All @@ -35,6 +32,7 @@ public class GraphQLInputObjectField implements GraphQLNamedSchemaElement, Graph
private final String description;
private final GraphQLInputType originalType;
private final Object defaultValue;
private final String deprecationReason;
private final InputValueDefinition definition;
private final DirectivesUtil.DirectivesHolder directives;

Expand Down Expand Up @@ -82,6 +80,10 @@ public GraphQLInputObjectField(String name, String description, GraphQLInputType
@Internal
@Deprecated
public GraphQLInputObjectField(String name, String description, GraphQLInputType type, Object defaultValue, List<GraphQLDirective> directives, InputValueDefinition definition) {
this(name, description, type, defaultValue, directives, definition, null);
}

private GraphQLInputObjectField(String name, String description, GraphQLInputType type, Object defaultValue, List<GraphQLDirective> directives, InputValueDefinition definition, String deprecationReason) {
assertValidName(name);
assertNotNull(type, () -> "type can't be null");
assertNotNull(directives, () -> "directives cannot be null");
Expand All @@ -92,6 +94,7 @@ public GraphQLInputObjectField(String name, String description, GraphQLInputType
this.description = description;
this.directives = new DirectivesUtil.DirectivesHolder(directives);
this.definition = definition;
this.deprecationReason = deprecationReason;
}

void replaceType(GraphQLInputType type) {
Expand All @@ -115,6 +118,14 @@ public String getDescription() {
return description;
}

public String getDeprecationReason() {
return deprecationReason;
}

public boolean isDeprecated() {
return deprecationReason != null;
}

public InputValueDefinition getDefinition() {
return definition;
}
Expand Down Expand Up @@ -233,6 +244,7 @@ public static class Builder extends GraphqlTypeBuilder {
private GraphQLInputType type;
private InputValueDefinition definition;
private final List<GraphQLDirective> directives = new ArrayList<>();
private String deprecationReason;

public Builder() {
}
Expand All @@ -243,7 +255,8 @@ public Builder(GraphQLInputObjectField existing) {
this.defaultValue = existing.getDefaultValue();
this.type = existing.originalType;
this.definition = existing.getDefinition();
DirectivesUtil.enforceAddAll(this.directives,existing.getDirectives());
this.deprecationReason = existing.deprecationReason;
DirectivesUtil.enforceAddAll(this.directives, existing.getDirectives());
}

@Override
Expand All @@ -269,6 +282,11 @@ public Builder definition(InputValueDefinition definition) {
return this;
}

public Builder deprecate(String deprecationReason) {
this.deprecationReason = deprecationReason;
return this;
}

public Builder type(GraphQLInputObjectType.Builder type) {
return type(type.build());
}
Expand Down Expand Up @@ -327,7 +345,8 @@ public GraphQLInputObjectField build() {
type,
defaultValue,
sort(directives, GraphQLInputObjectField.class, GraphQLDirective.class),
definition);
definition,
deprecationReason);
}
}
}
Loading