-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Handle repeated query directives #3270
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,7 @@ | |
| import graphql.schema.GraphQLDirective; | ||
| import graphql.schema.GraphQLSchema; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.LinkedHashMap; | ||
| import java.util.List; | ||
| import java.util.Locale; | ||
|
|
@@ -25,14 +26,14 @@ public class DirectivesResolver { | |
| public DirectivesResolver() { | ||
| } | ||
|
|
||
| public Map<String, GraphQLDirective> resolveDirectives(List<Directive> directives, GraphQLSchema schema, Map<String, Object> variables, GraphQLContext graphQLContext, Locale locale) { | ||
| public Map<String, List<GraphQLDirective>> resolveDirectives(List<Directive> directives, GraphQLSchema schema, Map<String, Object> variables, GraphQLContext graphQLContext, Locale locale) { | ||
| GraphQLCodeRegistry codeRegistry = schema.getCodeRegistry(); | ||
| Map<String, GraphQLDirective> directiveMap = new LinkedHashMap<>(); | ||
| Map<String, List<GraphQLDirective>> directiveMap = new LinkedHashMap<>(); | ||
| directives.forEach(directive -> { | ||
| GraphQLDirective protoType = schema.getDirective(directive.getName()); | ||
| if (protoType != null) { | ||
| GraphQLDirective newDirective = protoType.transform(builder -> buildArguments(builder, codeRegistry, protoType, directive, variables, graphQLContext, locale)); | ||
| directiveMap.put(newDirective.getName(), newDirective); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Previously this would just replace the last directive instance. Now it accumulates the values for repeated directives. |
||
| directiveMap.computeIfAbsent(newDirective.getName(), k -> new ArrayList<>()).add(newDirective); | ||
| } | ||
| }); | ||
| return ImmutableMap.copyOf(directiveMap); | ||
|
|
@@ -60,4 +61,4 @@ private void buildArguments(GraphQLDirective.Builder directiveBuilder, | |
| } | ||
| }); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -265,7 +265,7 @@ public static <T> CompletableFuture<List<T>> flatList(CompletableFuture<List<Lis | |
| return cf.thenApply(FpKit::flatList); | ||
| } | ||
|
|
||
| public static <T> List<T> flatList(List<List<T>> listLists) { | ||
| public static <T> List<T> flatList(Collection<List<T>> listLists) { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Needed as |
||
| return listLists.stream() | ||
| .flatMap(List::stream) | ||
| .collect(ImmutableList.toImmutableList()); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,8 @@ class QueryDirectivesImplTest extends Specification { | |
| directive @cached(forMillis : Int = 99) on FIELD | QUERY | ||
|
|
||
| directive @upper(place : String) on FIELD | ||
|
|
||
| directive @rep(place : String) repeatable on FIELD | ||
|
|
||
| type Query { | ||
| f : String | ||
|
|
@@ -24,9 +26,7 @@ class QueryDirectivesImplTest extends Specification { | |
|
|
||
| def schema = TestUtil.schema(sdl) | ||
|
|
||
|
|
||
| def "can get immediate directives"() { | ||
|
|
||
| def f1 = TestUtil.parseField("f1 @cached @upper") | ||
| def f2 = TestUtil.parseField("f2 @cached(forMillis : \$var) @timeout") | ||
|
|
||
|
|
@@ -68,7 +68,6 @@ class QueryDirectivesImplTest extends Specification { | |
| } | ||
|
|
||
| def "builder works as expected"() { | ||
|
|
||
| def f1 = TestUtil.parseField("f1 @cached @upper") | ||
| def f2 = TestUtil.parseField("f2 @cached(forMillis : \$var) @timeout") | ||
|
|
||
|
|
@@ -87,6 +86,28 @@ class QueryDirectivesImplTest extends Specification { | |
|
|
||
| then: | ||
| appliedDirectivesByName.keySet().sort() == ["cached", "timeout", "upper"] | ||
| } | ||
|
|
||
| def "gets repeated definitions"() { | ||
| def f1 = TestUtil.parseField("f1 @rep(place: \$var) @rep(place: \"HELLO\")") | ||
|
|
||
| def mergedField = MergedField.newMergedField([f1]).build() | ||
|
|
||
| def queryDirectives = QueryDirectives.newQueryDirectives() | ||
| .mergedField(mergedField) | ||
| .schema(schema) | ||
| .coercedVariables(CoercedVariables.of([var: "ABC"])) | ||
| .graphQLContext(GraphQLContext.getDefault()) | ||
| .locale(Locale.getDefault()) | ||
| .build() | ||
|
|
||
| when: | ||
| def appliedDirectivesByName = queryDirectives.getImmediateAppliedDirectivesByName() | ||
|
|
||
| then: | ||
| appliedDirectivesByName.keySet() == ["rep"] as Set | ||
| appliedDirectivesByName["rep"].size() == 2 | ||
| // Groovy is a pathway to many abilities some consider to be unnatural | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My favourite is groovy will ignore all 'private' modifier. I am not selfish. I can even share other's private with you.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lol you put this in to verify that I read all the way to the end, right? |
||
| appliedDirectivesByName["rep"].arguments.value.flatten().sort() == ["ABC", "HELLO"] | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should just return a
List<GraphQLDirecitve>since we don't even use the map result. It's immediately discarded as we callMap.values()