Skip to content

Commit

Permalink
Remove attributes from Argument annotation
Browse files Browse the repository at this point in the history
Prior to this commit, the `@Argument` annotation would support two
attributes: `required` and `defaultValue`, specifying whether arguments
should be considered as required and default values to use if they're
not present.

This can be problematic as this can already be specified at the schema
level.

To avoid duplication and invalid setups betweens schema and Controllers,
this commit removes those attributes in favor of the schema definition.

Closes gh-150
  • Loading branch information
bclozel committed Sep 24, 2021
1 parent e0952a2 commit b03097a
Show file tree
Hide file tree
Showing 5 changed files with 9 additions and 63 deletions.
2 changes: 0 additions & 2 deletions samples/webmvc-http/src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
management.endpoints.web.exposure.include=health,metrics,info

spring.graphql.schema.printer.enabled=true

spring.graph
7 changes: 3 additions & 4 deletions spring-graphql-docs/src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -577,8 +577,7 @@ values. The arguments are available as simple scalar values such as String, or a
of values for more complex input, or a `List` of values.

Use `@Argument` to access an argument for the field that maps to the handler method. You
can declare such a method parameter to be of any type. If necessary, Spring GraphQL
converts the value by serializing it to JSON first and then to the target type.
can declare such a method parameter to be of any type.

[source,java,indent=0,subs="verbatim,quotes"]
----
Expand All @@ -601,8 +600,8 @@ You can explicitly specify the argument name, for example `@Argument("bookInput"
it not specified, it defaults to the method parameter name, but this requires the
`-parameters` compiler flag with Java 8+ or debugging information from the compiler.

By default, an `@Argument` is required, but you can make it optional by setting the
`required` flag to false or by declaring the argument with `java.util.Optional`.
The "required" character of an `@Argument` or its default value is controlled at the schema
level.

You can use `@Argument` on a `Map<String, Object>` argument, to obtain all argument
values. The name attribute on `@Argument` must not be set.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,20 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


import org.springframework.core.annotation.AliasFor;

/**
* Annotation to bind a method parameter to a GraphQL input
* {@link graphql.schema.DataFetchingEnvironment#getArgument(String) argument}.
*
* <p>If the method parameter is {@link java.util.Map Map&lt;String, Object&gt;} or
* <p>If the method parameter is {@link java.util.Map Map&lt;String, Object&gt;}
* and a parameter name is not specified, then the map parameter is populated
* via {@link graphql.schema.DataFetchingEnvironment#getArguments()}.
*
* <p>This annotation does not specify whether the input argument is required
* and if it should use a default value: this should be done at the schema
* in order to be enforced by the GraphQL engine itself.
*
* @author Rossen Stoyanchev
* @since 1.0.0
*/
Expand All @@ -52,22 +55,4 @@
@AliasFor("value")
String name() default "";

/**
* Whether the input argument is required.
* <p>Defaults to {@code true}, leading to an exception being thrown
* if the argument is missing. Switch this to {@code false} if you prefer
* a {@code null} value when the parameter is not present.
* <p>Alternatively, provide a {@link #defaultValue}, which implicitly
* sets this flag to {@code false}.
*/
boolean required() default true;

/**
* The default value to use as a fallback when an input argument is
* not present or has an empty value.
* <p>Supplying a default value implicitly sets {@link #required} to
* {@code false}.
*/
String defaultValue() default ValueConstants.DEFAULT_NONE;

}
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,10 @@ public Object resolveArgument(MethodParameter parameter, DataFetchingEnvironment
}
}

Object rawValue = (ValueConstants.DEFAULT_NONE.equals(annotation.defaultValue()) ?
environment.getArgument(name) :
environment.getArgumentOrDefault(name, annotation.defaultValue()));

Object rawValue = environment.getArgument(name);
TypeDescriptor parameterType = new TypeDescriptor(parameter);

if (rawValue == null) {
if (annotation.required()) {
throw new MissingArgumentException(name, parameter);
}
return returnValue(rawValue, parameterType.getType());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,26 +86,6 @@ void shouldResolveJavaBeanArgument() throws Exception {
.hasFieldOrPropertyWithValue("authorId", 42L);
}

@Test
void shouldResolveDefaultValue() throws Exception {
Method findWithDefault = ClassUtils.getMethod(BookController.class, "findWithDefault", Long.class);
String payload = "{\"name\": \"test\" }";
DataFetchingEnvironment environment = initEnvironment(payload);
MethodParameter methodParameter = getMethodParameter(findWithDefault, 0);
Object result = resolver.resolveArgument(methodParameter, environment);
assertThat(result).isNotNull().isInstanceOf(Long.class).isEqualTo(42L);
}

@Test
void shouldNotFailIfArgumentNotRequired() throws Exception {
Method findByKeywords = ClassUtils.getMethod(BookController.class, "findByKeywords", List.class);
String payload = "{ }";
DataFetchingEnvironment environment = initEnvironment(payload);
MethodParameter methodParameter = getMethodParameter(findByKeywords, 0);
Object result = resolver.resolveArgument(methodParameter, environment);
assertThat(result).isNull();
}

@Test
void shouldResolveListOfJavaBeansArgument() throws Exception {
Method addBooks = ClassUtils.getMethod(BookController.class, "addBooks", List.class);
Expand Down Expand Up @@ -142,16 +122,6 @@ public Book bookById(@Argument Long id) {
return null;
}

@QueryMapping
public Book findWithDefault(@Argument(defaultValue = "42") Long id) {
return null;
}

@QueryMapping
public Book findByKeywords(@Argument(required = false) List<Keyword> keywords) {
return null;
}

@MutationMapping
public Book addBook(@Argument BookInput bookInput) {
return null;
Expand Down

0 comments on commit b03097a

Please sign in to comment.