Skip to content

Commit 562d39a

Browse files
committed
Revert "Remove ArgumentMapMethodArgumentResolver"
This reverts commit 7b30159.
1 parent 483ef31 commit 562d39a

File tree

8 files changed

+185
-82
lines changed

8 files changed

+185
-82
lines changed

spring-graphql-docs/src/docs/asciidoc/index.adoc

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,41 +1183,34 @@ Schema mapping handler methods can have any of the following method arguments:
11831183

11841184
| `@Argument`
11851185
| For access to a named field argument bound to a higher-level, typed Object.
1186-
11871186
See <<controllers.schema-mapping.argument>>.
11881187

11891188
| `@Argument Map<String, Object>`
1190-
| For access to the raw argument value.
1191-
1192-
See <<controllers.schema-mapping.argument>>.
1189+
| For access to the raw map of arguments, where `@Argument` does not have a
1190+
`name` attribute.
11931191

11941192
| `ArgumentValue`
11951193
| For access to a named field argument bound to a higher-level, typed Object along
11961194
with a flag to indicate if the input argument was omitted vs set to `null`.
1197-
11981195
See <<controllers.schema-mapping.argument-value>>.
11991196

12001197
| `@Arguments`
12011198
| For access to all field arguments bound to a higher-level, typed Object.
1202-
12031199
See <<controllers.schema-mapping.arguments>>.
12041200

12051201
| `@Arguments Map<String, Object>`
12061202
| For access to the raw map of arguments.
12071203

12081204
| `@ProjectedPayload` Interface
12091205
| For access to field arguments through a project interface.
1210-
12111206
See <<controllers.schema-mapping.projectedpayload.argument>>.
12121207

12131208
| "Source"
12141209
| For access to the source (i.e. parent/container) instance of the field.
1215-
12161210
See <<controllers.schema-mapping.source>>.
12171211

12181212
| `DataLoader`
12191213
| For access to a `DataLoader` in the `DataLoaderRegistry`.
1220-
12211214
See <<controllers.schema-mapping.data-loader>>.
12221215

12231216
| `@ContextValue`
@@ -1297,26 +1290,8 @@ are enforced by GraphQL Java.
12971290
If binding fails, a `BindException` is raised with binding issues accumulated as field
12981291
errors where the `field` of each error is the argument path where the issue occurred.
12991292

1300-
You can use `@Argument` with a `Map<String, Object>` argument, to obtain the raw value of
1301-
the argument. For example:
1302-
1303-
[source,java,indent=0,subs="verbatim,quotes"]
1304-
----
1305-
@Controller
1306-
public class BookController {
1307-
1308-
@MutationMapping
1309-
public Book addBook(@Argument Map<String, Object> bookInput) {
1310-
// ...
1311-
}
1312-
}
1313-
----
1314-
1315-
NOTE: Prior to 1.2, `@Argument Map<String, Object>` returned the full arguments map if
1316-
the annotation did not specify a name. After 1.2, `@Argument` with
1317-
`Map<String, Object>` always returns the raw argument value, matching either to the name
1318-
specified in the annotation, or to the parameter name. For access to the full arguments
1319-
map, please use <<controllers.schema-mapping.arguments>> instead.
1293+
You can use `@Argument` with a `Map<String, Object>` argument, to obtain the raw map of
1294+
all argument values. The name attribute on `@Argument` must not be set.
13201295

13211296

13221297
[[controllers.schema-mapping.argument-value]]

spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/Argument.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -40,13 +40,12 @@
4040
* {@code field} of each error is the argument path where the issue occurred.
4141
*
4242
* <p>If the method parameter is {@link java.util.Map Map&lt;String, Object&gt;}
43-
* then the raw argument value for the named argument is used. For access to the
44-
* full {@link graphql.schema.DataFetchingEnvironment#getArguments() arguments}
45-
* map, use {@link Arguments @Arguments} instead.
43+
* and a parameter name is not specified, then the resolves value is the raw
44+
* {@link graphql.schema.DataFetchingEnvironment#getArguments() arguments} map.
4645
*
47-
* <p>This annotation has neither a "required" flag nor the option to specify a
48-
* default value, both of which can be specified at the GraphQL schema level
49-
* and are enforced by the GraphQL Java engine.
46+
* <p>Note that this annotation has neither a "required" flag nor the option to
47+
* specify a default value, both of which can be specified at the GraphQL schema
48+
* level and are enforced by the GraphQL Java engine.
5049
*
5150
* @author Rossen Stoyanchev
5251
* @since 1.0.0

spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerConfigurer.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ private HandlerMethodArgumentResolverComposite initArgumentResolvers() {
189189
// Must be ahead of ArgumentMethodArgumentResolver
190190
resolvers.addResolver(new ProjectedPayloadMethodArgumentResolver(obtainApplicationContext()));
191191
}
192+
resolvers.addResolver(new ArgumentMapMethodArgumentResolver());
192193
GraphQlArgumentBinder argumentBinder = new GraphQlArgumentBinder(this.conversionService);
193194
resolvers.addResolver(new ArgumentMethodArgumentResolver(argumentBinder));
194195
resolvers.addResolver(new ArgumentsMethodArgumentResolver(argumentBinder));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright 2002-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.graphql.data.method.annotation.support;
18+
19+
import java.util.Map;
20+
21+
import graphql.schema.DataFetchingEnvironment;
22+
23+
import org.springframework.core.MethodParameter;
24+
import org.springframework.graphql.data.method.HandlerMethodArgumentResolver;
25+
import org.springframework.graphql.data.method.annotation.Argument;
26+
import org.springframework.graphql.data.method.annotation.Arguments;
27+
import org.springframework.util.StringUtils;
28+
29+
30+
/**
31+
* Resolves a {@link Map} method parameter for access to the raw arguments map.
32+
* Supported with the following:
33+
* <ul>
34+
* <li>{@link Map} argument annotated with {@link Argument @Argument} where the
35+
* annotation does not explicitly specify a name.
36+
* <li>{@link Map} argument annotated with {@link Arguments @Arguments}.
37+
* </ul>
38+
*
39+
* @author Rossen Stoyanchev
40+
* @since 1.0.0
41+
*/
42+
public class ArgumentMapMethodArgumentResolver implements HandlerMethodArgumentResolver {
43+
44+
@Override
45+
public boolean supportsParameter(MethodParameter parameter) {
46+
return (checkArgumentMap(parameter) || checkArgumentsMap(parameter));
47+
}
48+
49+
private static boolean checkArgumentMap(MethodParameter parameter) {
50+
Argument argument = parameter.getParameterAnnotation(Argument.class);
51+
return (argument != null &&
52+
Map.class.isAssignableFrom(parameter.getParameterType()) &&
53+
!StringUtils.hasText(argument.name()));
54+
}
55+
56+
private static boolean checkArgumentsMap(MethodParameter parameter) {
57+
Arguments argument = parameter.getParameterAnnotation(Arguments.class);
58+
return (argument != null && Map.class.isAssignableFrom(parameter.getParameterType()));
59+
}
60+
61+
@Override
62+
public Object resolveArgument(MethodParameter parameter, DataFetchingEnvironment environment) {
63+
return environment.getArguments();
64+
}
65+
66+
}

spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ArgumentMethodArgumentResolver.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
* Resolver for a method parameter that is annotated with
3131
* {@link Argument @Argument}. The specified raw argument value is obtained via
3232
* {@link DataFetchingEnvironment#getArgument(String)} and bound to a higher
33-
* level object via {@link GraphQlArgumentBinder} to match the target method
33+
* level object, via {@link GraphQlArgumentBinder}, to match the target method
3434
* parameter type.
3535
*
3636
* <p>This resolver also supports wrapping the target object with
@@ -45,7 +45,9 @@
4545
* @author Rossen Stoyanchev
4646
* @author Brian Clozel
4747
* @since 1.0.0
48-
* @see org.springframework.graphql.data.method.annotation.support.ArgumentsMethodArgumentResolver
48+
* @see org.springframework.graphql.data.method.annotation.Argument
49+
* @see org.springframework.graphql.data.method.annotation.Arguments
50+
* @see org.springframework.graphql.data.GraphQlArgumentBinder
4951
*/
5052
public class ArgumentMethodArgumentResolver implements HandlerMethodArgumentResolver {
5153

@@ -79,8 +81,7 @@ static String getArgumentName(MethodParameter parameter) {
7981
}
8082
}
8183
else if (parameter.getParameterType() != ArgumentValue.class) {
82-
throw new IllegalStateException(
83-
"Expected either @Argument or a method parameter of type ArgumentValue");
84+
throw new IllegalStateException("Expected @Argument annotation");
8485
}
8586

8687
String parameterName = parameter.getParameterName();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* Copyright 2020-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.graphql.data.method.annotation.support;
18+
19+
20+
import java.util.Collections;
21+
import java.util.Map;
22+
23+
import org.junit.jupiter.api.Test;
24+
25+
import org.springframework.core.MethodParameter;
26+
import org.springframework.graphql.Book;
27+
import org.springframework.graphql.data.method.HandlerMethodArgumentResolver;
28+
import org.springframework.graphql.data.method.annotation.Argument;
29+
import org.springframework.graphql.data.method.annotation.Arguments;
30+
import org.springframework.graphql.data.method.annotation.QueryMapping;
31+
import org.springframework.stereotype.Controller;
32+
33+
import static org.assertj.core.api.Assertions.assertThat;
34+
35+
/**
36+
* Unit tests for {@link ArgumentMethodArgumentResolver}.
37+
* @author Rossen Stoyanchev
38+
*/
39+
class ArgumentMapMethodArgumentResolverTests extends ArgumentResolverTestSupport {
40+
41+
private final HandlerMethodArgumentResolver resolver = new ArgumentMapMethodArgumentResolver();
42+
43+
44+
@Test
45+
void shouldSupportAnnotatedParameters() {
46+
MethodParameter param = methodParam(BookController.class, "argumentMap", Map.class);
47+
assertThat(this.resolver.supportsParameter(param)).isTrue();
48+
49+
param = methodParam(BookController.class, "argumentsMap", Map.class);
50+
assertThat(this.resolver.supportsParameter(param)).isTrue();
51+
52+
param = methodParam(BookController.class, "argument", Long.class);
53+
assertThat(this.resolver.supportsParameter(param)).isFalse();
54+
55+
param = methodParam(BookController.class, "namedArgumentMap", Map.class);
56+
assertThat(this.resolver.supportsParameter(param)).isFalse();
57+
58+
param = methodParam(BookController.class, "notAnnotated", String.class);
59+
assertThat(this.resolver.supportsParameter(param)).isFalse();
60+
}
61+
62+
@Test
63+
void shouldResolveRawArgumentsMap() throws Exception {
64+
Object result = this.resolver.resolveArgument(
65+
methodParam(BookController.class, "argumentMap", Map.class),
66+
environment("{\"id\": 42 }"));
67+
68+
assertThat(result).isNotNull().isInstanceOf(Map.class).isEqualTo(Collections.singletonMap("id", 42));
69+
}
70+
71+
72+
@SuppressWarnings({"ConstantConditions", "unused"})
73+
@Controller
74+
static class BookController {
75+
76+
@QueryMapping
77+
public Book argumentMap(@Argument Map<?, ?> args) {
78+
return null;
79+
}
80+
81+
@QueryMapping
82+
public Book argumentsMap(@Arguments Map<?, ?> args) {
83+
return null;
84+
}
85+
86+
@QueryMapping
87+
public Book argument(@Argument Long id) {
88+
return null;
89+
}
90+
91+
@QueryMapping
92+
public Book namedArgumentMap(@Argument(name = "book") Map<?, ?> book) {
93+
return null;
94+
}
95+
96+
public void notAnnotated(String param) {
97+
}
98+
99+
}
100+
101+
}

spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ArgumentMethodArgumentResolverTests.java

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2023 the original author or authors.
2+
* Copyright 2020-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@
1818

1919

2020
import java.util.List;
21-
import java.util.Map;
2221

2322
import org.junit.jupiter.api.Test;
2423

@@ -53,9 +52,6 @@ void supportsParameter() {
5352
param = methodParam(BookController.class, "addBook", ArgumentValue.class);
5453
assertThat(this.resolver.supportsParameter(param)).isTrue();
5554

56-
param = methodParam(BookController.class, "rawArgumentValue", Map.class);
57-
assertThat(this.resolver.supportsParameter(param)).isTrue();
58-
5955
param = methodParam(BookController.class, "notSupported", String.class);
6056
assertThat(this.resolver.supportsParameter(param)).isFalse();
6157
}
@@ -117,17 +113,6 @@ void shouldResolveArgumentWithConversionService() throws Exception {
117113
assertThat(result).isNotNull().isInstanceOf(Keyword.class).hasFieldOrPropertyWithValue("term", "test");
118114
}
119115

120-
@Test
121-
void shouldResolveRawArgumentValue() throws Exception {
122-
Map<String, Object> result = (Map<String, Object>) this.resolver.resolveArgument(
123-
methodParam(BookController.class, "rawArgumentValue", Map.class),
124-
environment("{\"bookInput\": { \"name\": \"test name\", \"authorId\": 42} }"));
125-
126-
assertThat(result)
127-
.containsEntry("name", "test name")
128-
.containsEntry("authorId", 42);
129-
}
130-
131116

132117
@SuppressWarnings({"ConstantConditions", "unused"})
133118
@Controller
@@ -162,13 +147,8 @@ public List<Book> bookByKeyword(@Argument Keyword keyword) {
162147
return null;
163148
}
164149

165-
@MutationMapping
166-
public Book rawArgumentValue(@Argument Map<?, ?> bookInput) {
167-
return null;
168-
}
169150
}
170151

171-
172152
@SuppressWarnings({"NotNullFieldNotInitialized", "unused"})
173153
static class BookInput {
174154

0 commit comments

Comments
 (0)