Revert "Remove ArgumentMapMethodArgumentResolver"

This reverts commit 7b30159109.
This commit is contained in:
rstoyanchev
2023-02-01 09:46:14 +00:00
parent 483ef31b5f
commit 562d39a9a2
8 changed files with 185 additions and 82 deletions

View File

@@ -1183,23 +1183,19 @@ Schema mapping handler methods can have any of the following method arguments:
| `@Argument`
| For access to a named field argument bound to a higher-level, typed Object.
See <<controllers.schema-mapping.argument>>.
| `@Argument Map<String, Object>`
| For access to the raw argument value.
See <<controllers.schema-mapping.argument>>.
| For access to the raw map of arguments, where `@Argument` does not have a
`name` attribute.
| `ArgumentValue`
| For access to a named field argument bound to a higher-level, typed Object along
with a flag to indicate if the input argument was omitted vs set to `null`.
See <<controllers.schema-mapping.argument-value>>.
| `@Arguments`
| For access to all field arguments bound to a higher-level, typed Object.
See <<controllers.schema-mapping.arguments>>.
| `@Arguments Map<String, Object>`
@@ -1207,17 +1203,14 @@ See <<controllers.schema-mapping.arguments>>.
| `@ProjectedPayload` Interface
| For access to field arguments through a project interface.
See <<controllers.schema-mapping.projectedpayload.argument>>.
| "Source"
| For access to the source (i.e. parent/container) instance of the field.
See <<controllers.schema-mapping.source>>.
| `DataLoader`
| For access to a `DataLoader` in the `DataLoaderRegistry`.
See <<controllers.schema-mapping.data-loader>>.
| `@ContextValue`
@@ -1297,26 +1290,8 @@ are enforced by GraphQL Java.
If binding fails, a `BindException` is raised with binding issues accumulated as field
errors where the `field` of each error is the argument path where the issue occurred.
You can use `@Argument` with a `Map<String, Object>` argument, to obtain the raw value of
the argument. For example:
[source,java,indent=0,subs="verbatim,quotes"]
----
@Controller
public class BookController {
@MutationMapping
public Book addBook(@Argument Map<String, Object> bookInput) {
// ...
}
}
----
NOTE: Prior to 1.2, `@Argument Map<String, Object>` returned the full arguments map if
the annotation did not specify a name. After 1.2, `@Argument` with
`Map<String, Object>` always returns the raw argument value, matching either to the name
specified in the annotation, or to the parameter name. For access to the full arguments
map, please use <<controllers.schema-mapping.arguments>> instead.
You can use `@Argument` with a `Map<String, Object>` argument, to obtain the raw map of
all argument values. The name attribute on `@Argument` must not be set.
[[controllers.schema-mapping.argument-value]]

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,13 +40,12 @@ import org.springframework.validation.BindException;
* {@code field} of each error is the argument path where the issue occurred.
*
* <p>If the method parameter is {@link java.util.Map Map&lt;String, Object&gt;}
* then the raw argument value for the named argument is used. For access to the
* full {@link graphql.schema.DataFetchingEnvironment#getArguments() arguments}
* map, use {@link Arguments @Arguments} instead.
* and a parameter name is not specified, then the resolves value is the raw
* {@link graphql.schema.DataFetchingEnvironment#getArguments() arguments} map.
*
* <p>This annotation has neither a "required" flag nor the option to specify a
* default value, both of which can be specified at the GraphQL schema level
* and are enforced by the GraphQL Java engine.
* <p>Note that this annotation has neither a "required" flag nor the option to
* specify a default value, both of which can be specified at the GraphQL schema
* level and are enforced by the GraphQL Java engine.
*
* @author Rossen Stoyanchev
* @since 1.0.0

View File

@@ -189,6 +189,7 @@ public class AnnotatedControllerConfigurer
// Must be ahead of ArgumentMethodArgumentResolver
resolvers.addResolver(new ProjectedPayloadMethodArgumentResolver(obtainApplicationContext()));
}
resolvers.addResolver(new ArgumentMapMethodArgumentResolver());
GraphQlArgumentBinder argumentBinder = new GraphQlArgumentBinder(this.conversionService);
resolvers.addResolver(new ArgumentMethodArgumentResolver(argumentBinder));
resolvers.addResolver(new ArgumentsMethodArgumentResolver(argumentBinder));

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.graphql.data.method.annotation.support;
import java.util.Map;
import graphql.schema.DataFetchingEnvironment;
import org.springframework.core.MethodParameter;
import org.springframework.graphql.data.method.HandlerMethodArgumentResolver;
import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.Arguments;
import org.springframework.util.StringUtils;
/**
* Resolves a {@link Map} method parameter for access to the raw arguments map.
* Supported with the following:
* <ul>
* <li>{@link Map} argument annotated with {@link Argument @Argument} where the
* annotation does not explicitly specify a name.
* <li>{@link Map} argument annotated with {@link Arguments @Arguments}.
* </ul>
*
* @author Rossen Stoyanchev
* @since 1.0.0
*/
public class ArgumentMapMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return (checkArgumentMap(parameter) || checkArgumentsMap(parameter));
}
private static boolean checkArgumentMap(MethodParameter parameter) {
Argument argument = parameter.getParameterAnnotation(Argument.class);
return (argument != null &&
Map.class.isAssignableFrom(parameter.getParameterType()) &&
!StringUtils.hasText(argument.name()));
}
private static boolean checkArgumentsMap(MethodParameter parameter) {
Arguments argument = parameter.getParameterAnnotation(Arguments.class);
return (argument != null && Map.class.isAssignableFrom(parameter.getParameterType()));
}
@Override
public Object resolveArgument(MethodParameter parameter, DataFetchingEnvironment environment) {
return environment.getArguments();
}
}

View File

@@ -30,7 +30,7 @@ import org.springframework.util.StringUtils;
* Resolver for a method parameter that is annotated with
* {@link Argument @Argument}. The specified raw argument value is obtained via
* {@link DataFetchingEnvironment#getArgument(String)} and bound to a higher
* level object via {@link GraphQlArgumentBinder} to match the target method
* level object, via {@link GraphQlArgumentBinder}, to match the target method
* parameter type.
*
* <p>This resolver also supports wrapping the target object with
@@ -45,7 +45,9 @@ import org.springframework.util.StringUtils;
* @author Rossen Stoyanchev
* @author Brian Clozel
* @since 1.0.0
* @see org.springframework.graphql.data.method.annotation.support.ArgumentsMethodArgumentResolver
* @see org.springframework.graphql.data.method.annotation.Argument
* @see org.springframework.graphql.data.method.annotation.Arguments
* @see org.springframework.graphql.data.GraphQlArgumentBinder
*/
public class ArgumentMethodArgumentResolver implements HandlerMethodArgumentResolver {
@@ -79,8 +81,7 @@ public class ArgumentMethodArgumentResolver implements HandlerMethodArgumentReso
}
}
else if (parameter.getParameterType() != ArgumentValue.class) {
throw new IllegalStateException(
"Expected either @Argument or a method parameter of type ArgumentValue");
throw new IllegalStateException("Expected @Argument annotation");
}
String parameterName = parameter.getParameterName();

View File

@@ -0,0 +1,101 @@
/*
* Copyright 2020-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.graphql.data.method.annotation.support;
import java.util.Collections;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.springframework.core.MethodParameter;
import org.springframework.graphql.Book;
import org.springframework.graphql.data.method.HandlerMethodArgumentResolver;
import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.Arguments;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.stereotype.Controller;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Unit tests for {@link ArgumentMethodArgumentResolver}.
* @author Rossen Stoyanchev
*/
class ArgumentMapMethodArgumentResolverTests extends ArgumentResolverTestSupport {
private final HandlerMethodArgumentResolver resolver = new ArgumentMapMethodArgumentResolver();
@Test
void shouldSupportAnnotatedParameters() {
MethodParameter param = methodParam(BookController.class, "argumentMap", Map.class);
assertThat(this.resolver.supportsParameter(param)).isTrue();
param = methodParam(BookController.class, "argumentsMap", Map.class);
assertThat(this.resolver.supportsParameter(param)).isTrue();
param = methodParam(BookController.class, "argument", Long.class);
assertThat(this.resolver.supportsParameter(param)).isFalse();
param = methodParam(BookController.class, "namedArgumentMap", Map.class);
assertThat(this.resolver.supportsParameter(param)).isFalse();
param = methodParam(BookController.class, "notAnnotated", String.class);
assertThat(this.resolver.supportsParameter(param)).isFalse();
}
@Test
void shouldResolveRawArgumentsMap() throws Exception {
Object result = this.resolver.resolveArgument(
methodParam(BookController.class, "argumentMap", Map.class),
environment("{\"id\": 42 }"));
assertThat(result).isNotNull().isInstanceOf(Map.class).isEqualTo(Collections.singletonMap("id", 42));
}
@SuppressWarnings({"ConstantConditions", "unused"})
@Controller
static class BookController {
@QueryMapping
public Book argumentMap(@Argument Map<?, ?> args) {
return null;
}
@QueryMapping
public Book argumentsMap(@Arguments Map<?, ?> args) {
return null;
}
@QueryMapping
public Book argument(@Argument Long id) {
return null;
}
@QueryMapping
public Book namedArgumentMap(@Argument(name = "book") Map<?, ?> book) {
return null;
}
public void notAnnotated(String param) {
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2023 the original author or authors.
* Copyright 2020-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@ package org.springframework.graphql.data.method.annotation.support;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
@@ -53,9 +52,6 @@ class ArgumentMethodArgumentResolverTests extends ArgumentResolverTestSupport {
param = methodParam(BookController.class, "addBook", ArgumentValue.class);
assertThat(this.resolver.supportsParameter(param)).isTrue();
param = methodParam(BookController.class, "rawArgumentValue", Map.class);
assertThat(this.resolver.supportsParameter(param)).isTrue();
param = methodParam(BookController.class, "notSupported", String.class);
assertThat(this.resolver.supportsParameter(param)).isFalse();
}
@@ -117,17 +113,6 @@ class ArgumentMethodArgumentResolverTests extends ArgumentResolverTestSupport {
assertThat(result).isNotNull().isInstanceOf(Keyword.class).hasFieldOrPropertyWithValue("term", "test");
}
@Test
void shouldResolveRawArgumentValue() throws Exception {
Map<String, Object> result = (Map<String, Object>) this.resolver.resolveArgument(
methodParam(BookController.class, "rawArgumentValue", Map.class),
environment("{\"bookInput\": { \"name\": \"test name\", \"authorId\": 42} }"));
assertThat(result)
.containsEntry("name", "test name")
.containsEntry("authorId", 42);
}
@SuppressWarnings({"ConstantConditions", "unused"})
@Controller
@@ -162,13 +147,8 @@ class ArgumentMethodArgumentResolverTests extends ArgumentResolverTestSupport {
return null;
}
@MutationMapping
public Book rawArgumentValue(@Argument Map<?, ?> bookInput) {
return null;
}
}
@SuppressWarnings({"NotNullFieldNotInitialized", "unused"})
static class BookInput {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2023 the original author or authors.
* Copyright 2020-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,9 +17,6 @@
package org.springframework.graphql.data.method.annotation.support;
import java.util.Collections;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.springframework.core.MethodParameter;
@@ -30,7 +27,6 @@ import org.springframework.graphql.data.GraphQlArgumentBinder;
import org.springframework.graphql.data.method.HandlerMethodArgumentResolver;
import org.springframework.graphql.data.method.annotation.Arguments;
import org.springframework.graphql.data.method.annotation.MutationMapping;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.stereotype.Controller;
import static org.assertj.core.api.Assertions.assertThat;
@@ -49,9 +45,6 @@ class ArgumentsMethodArgumentResolverTests extends ArgumentResolverTestSupport {
void shouldSupportAnnotatedParameters() {
MethodParameter methodParameter = methodParam(BookController.class, "addBook", BookInput.class);
assertThat(resolver.supportsParameter(methodParameter)).isTrue();
methodParameter = methodParam(BookController.class, "argumentsMap", Map.class);
assertThat(resolver.supportsParameter(methodParameter)).isTrue();
}
@Test
@@ -78,15 +71,6 @@ class ArgumentsMethodArgumentResolverTests extends ArgumentResolverTestSupport {
});
}
@Test
void shouldResolveRawArgumentsMap() throws Exception {
Object result = this.resolver.resolveArgument(
methodParam(BookController.class, "argumentsMap", Map.class),
environment("{\"id\": 42 }"));
assertThat(result).isNotNull().isEqualTo(Collections.singletonMap("id", 42));
}
@SuppressWarnings({"ConstantConditions", "unused"})
@Controller
@@ -100,10 +84,6 @@ class ArgumentsMethodArgumentResolverTests extends ArgumentResolverTestSupport {
return null;
}
@QueryMapping
public Book argumentsMap(@Arguments Map<?, ?> map) {
return null;
}
}
@SuppressWarnings({"NotNullFieldNotInitialized", "unused"})