Skip to content

Commit

Permalink
Remove ArgumentMapMethodArgumentResolver
Browse files Browse the repository at this point in the history
Dropping this the dedicated resolver for @argument Map<String, Object>
leaves it to ArgumentMethodArgumentResolver and
ArgumentsMethodArgumentResolver to handle the case of
Map<String, Object>, treating it either as a raw argument value for a
named argument, or as the full raw arguments map.

Closes gh-548
  • Loading branch information
rstoyanchev committed Feb 1, 2023
1 parent d261b29 commit 1ae33a8
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 185 deletions.
33 changes: 29 additions & 4 deletions spring-graphql-docs/src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1183,34 +1183,41 @@ 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 map of arguments, where `@Argument` does not have a
`name` attribute.
| For access to the raw argument value.

See <<controllers.schema-mapping.argument>>.

| `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>`
| For access to the raw map of 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`
Expand Down Expand Up @@ -1290,8 +1297,26 @@ 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 map of
all argument values. The name attribute on `@Argument` must not be set.
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.


[[controllers.schema-mapping.argument-value]]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2023 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.
Expand Down Expand Up @@ -40,12 +40,13 @@
* {@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;}
* and a parameter name is not specified, then the resolves value is the raw
* {@link graphql.schema.DataFetchingEnvironment#getArguments() arguments} map.
* 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.
*
* <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.
* <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.
*
* @author Rossen Stoyanchev
* @since 1.0.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,6 @@ private HandlerMethodArgumentResolverComposite initArgumentResolvers() {
// 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));
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
* 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
Expand All @@ -45,9 +45,7 @@
* @author Rossen Stoyanchev
* @author Brian Clozel
* @since 1.0.0
* @see org.springframework.graphql.data.method.annotation.Argument
* @see org.springframework.graphql.data.method.annotation.Arguments
* @see org.springframework.graphql.data.GraphQlArgumentBinder
* @see org.springframework.graphql.data.method.annotation.support.ArgumentsMethodArgumentResolver
*/
public class ArgumentMethodArgumentResolver implements HandlerMethodArgumentResolver {

Expand Down Expand Up @@ -81,7 +79,8 @@ static String getArgumentName(MethodParameter parameter) {
}
}
else if (parameter.getParameterType() != ArgumentValue.class) {
throw new IllegalStateException("Expected @Argument annotation");
throw new IllegalStateException(
"Expected either @Argument or a method parameter of type ArgumentValue");
}

String parameterName = parameter.getParameterName();
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2020-2022 the original author or authors.
* Copyright 2020-2023 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.
Expand All @@ -18,6 +18,7 @@


import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -52,6 +53,9 @@ void supportsParameter() {
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();
}
Expand Down Expand Up @@ -113,6 +117,17 @@ void shouldResolveArgumentWithConversionService() throws Exception {
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
Expand Down Expand Up @@ -147,8 +162,13 @@ public List<Book> bookByKeyword(@Argument Keyword keyword) {
return null;
}

@MutationMapping
public Book rawArgumentValue(@Argument Map<?, ?> bookInput) {
return null;
}
}


@SuppressWarnings({"NotNullFieldNotInitialized", "unused"})
static class BookInput {

Expand Down
Loading

0 comments on commit 1ae33a8

Please sign in to comment.