From da00c8beaaf1de3989d026b35af0875ca8b94823 Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Mon, 20 Mar 2023 07:02:10 +0000 Subject: [PATCH] Support Optional method argument See gh-620 --- .../support/SortMethodArgumentResolver.java | 7 ++- .../SortMethodArgumentResolverTests.java | 46 ++++++++++++------- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SortMethodArgumentResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SortMethodArgumentResolver.java index 43d6397c..9929ae87 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SortMethodArgumentResolver.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SortMethodArgumentResolver.java @@ -17,6 +17,8 @@ package org.springframework.graphql.data.method.annotation.support; +import java.util.Optional; + import graphql.schema.DataFetchingEnvironment; import org.springframework.core.MethodParameter; @@ -45,12 +47,15 @@ public class SortMethodArgumentResolver implements HandlerMethodArgumentResolver @Override public boolean supportsParameter(MethodParameter parameter) { - return parameter.getParameterType().equals(Sort.class); + return parameter.nestedIfOptional().getNestedParameterType().equals(Sort.class); } @Override public Object resolveArgument(MethodParameter parameter, DataFetchingEnvironment environment) { Sort sort = this.sortStrategy.extract(environment); + if (parameter.isOptional()) { + return Optional.ofNullable(sort); + } return (sort != null ? sort : Sort.unsorted()); } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SortMethodArgumentResolverTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SortMethodArgumentResolverTests.java index bab6bf57..aa556d62 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SortMethodArgumentResolverTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SortMethodArgumentResolverTests.java @@ -17,6 +17,8 @@ package org.springframework.graphql.data.method.annotation.support; import java.util.List; +import java.util.Optional; +import java.util.function.Function; import java.util.stream.Collectors; import graphql.schema.DataFetchingEnvironment; @@ -28,7 +30,6 @@ import org.springframework.graphql.Book; import org.springframework.graphql.BookCriteria; import org.springframework.graphql.data.method.annotation.QueryMapping; import org.springframework.graphql.data.query.AbstractSortStrategy; -import org.springframework.graphql.data.query.SortStrategy; import static org.assertj.core.api.Assertions.assertThat; @@ -39,25 +40,35 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class SortMethodArgumentResolverTests extends ArgumentResolverTestSupport { + private final SortMethodArgumentResolver resolver = new SortMethodArgumentResolver(new MySortStrategy()); + private final MethodParameter param = methodParam(BookController.class, "getBooks", Sort.class); + private final MethodParameter paramOptional = methodParam(BookController.class, "getBooksOptional", Optional.class); + @Test void supports() { - SortMethodArgumentResolver resolver = resolver(new SimpleSortStrategy()); - assertThat(resolver.supportsParameter(this.param)).isTrue(); - + assertThat(this.resolver.supportsParameter(this.param)).isTrue(); + assertThat(this.resolver.supportsParameter(this.paramOptional)).isTrue(); + MethodParameter param = methodParam(BookController.class, "getBooksByCriteria", BookCriteria.class); - assertThat(resolver.supportsParameter(param)).isFalse(); + assertThat(this.resolver.supportsParameter(param)).isFalse(); } + @SuppressWarnings({"unchecked", "DataFlowIssue", "OptionalGetWithoutIsPresent"}) @Test void resolve() throws Exception { + testResolver(env -> (Sort) this.resolver.resolveArgument(this.param, env)); + testResolver(env -> ((Optional) this.resolver.resolveArgument(this.paramOptional, env)).get()); + } + + private void testResolver(Function resolveFunction) throws Exception { DataFetchingEnvironment environment = environment(""" { "sortFields": ["firstName", "lastName", "id"], "sortDirection": "DESC"}" """); - Sort sort = (Sort) resolver(new SimpleSortStrategy()).resolveArgument(param, environment); + Sort sort = resolveFunction.apply(environment); assertThat(sort.stream().collect(Collectors.toList())) .hasSize(3) @@ -67,12 +78,8 @@ public class SortMethodArgumentResolverTests extends ArgumentResolverTestSupport new Sort.Order(Sort.Direction.DESC, "id")); } - private SortMethodArgumentResolver resolver(SortStrategy sortStrategy) { - return new SortMethodArgumentResolver(sortStrategy); - } - - @SuppressWarnings({"DataFlowIssue", "unused"}) + @SuppressWarnings({"unused", "DataFlowIssue", "OptionalUsedAsFieldOrParameterType"}) private static class BookController { @QueryMapping @@ -80,6 +87,11 @@ public class SortMethodArgumentResolverTests extends ArgumentResolverTestSupport return null; } + @QueryMapping + public List getBooksOptional(Optional sort) { + return null; + } + @QueryMapping public List getBooksByCriteria(BookCriteria criteria) { return null; @@ -88,17 +100,17 @@ public class SortMethodArgumentResolverTests extends ArgumentResolverTestSupport } - private static class SimpleSortStrategy extends AbstractSortStrategy { + private static class MySortStrategy extends AbstractSortStrategy { @Override - protected List getProperties(DataFetchingEnvironment environment) { - return environment.getArgument("sortFields"); + protected List getProperties(DataFetchingEnvironment env) { + return env.getArgument("sortFields"); } @Override - protected Sort.Direction getDirection(DataFetchingEnvironment environment) { - return (environment.containsArgument("sortDirection") ? - Sort.Direction.valueOf(environment.getArgument("sortDirection")) : null); + protected Sort.Direction getDirection(DataFetchingEnvironment env) { + String direction = env.getArgument("sortDirection"); + return (direction != null ? Sort.Direction.valueOf(direction) : null); } }