strategy) {
+ super(strategy);
}
@Override
public boolean supportsParameter(MethodParameter parameter) {
- return parameter.getParameterType().equals(ScrollRequest.class);
+ return parameter.getParameterType().equals(ScrollSubrange.class);
}
- protected ScrollRequest createRequest(@Nullable ScrollPosition position, @Nullable Integer size, boolean forward) {
- return new ScrollRequest(position, size, forward);
+ protected ScrollSubrange createSubrange(@Nullable ScrollPosition pos, @Nullable Integer size, boolean forward) {
+ return new ScrollSubrange(pos, size, forward);
}
}
diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/PaginationRequestMethodArgumentResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SubrangeMethodArgumentResolver.java
similarity index 73%
rename from spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/PaginationRequestMethodArgumentResolver.java
rename to spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SubrangeMethodArgumentResolver.java
index 5a7d493a..08319010 100644
--- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/PaginationRequestMethodArgumentResolver.java
+++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SubrangeMethodArgumentResolver.java
@@ -22,23 +22,23 @@ import graphql.schema.DataFetchingEnvironment;
import org.springframework.core.MethodParameter;
import org.springframework.graphql.data.method.HandlerMethodArgumentResolver;
import org.springframework.graphql.data.pagination.CursorStrategy;
-import org.springframework.graphql.data.pagination.PaginationRequest;
+import org.springframework.graphql.data.pagination.Subrange;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
- * Resolver for a method argument of type {@link PaginationRequest} initialized
+ * Resolver for a method argument of type {@link Subrange} initialized
* from "first", "last", "before", and "after" GraphQL arguments.
*
* @author Rossen Stoyanchev
* @since 1.2
*/
-public class PaginationRequestMethodArgumentResolver implements HandlerMethodArgumentResolver {
+public class SubrangeMethodArgumentResolver
implements HandlerMethodArgumentResolver {
private final CursorStrategy
cursorStrategy;
- public PaginationRequestMethodArgumentResolver(CursorStrategy
cursorStrategy) {
+ public SubrangeMethodArgumentResolver(CursorStrategy
cursorStrategy) {
Assert.notNull(cursorStrategy, "CursorStrategy is required");
this.cursorStrategy = cursorStrategy;
}
@@ -46,7 +46,7 @@ public class PaginationRequestMethodArgumentResolver
implements HandlerMethod
@Override
public boolean supportsParameter(MethodParameter parameter) {
- return (parameter.getParameterType().equals(PaginationRequest.class) &&
+ return (parameter.getParameterType().equals(Subrange.class) &&
this.cursorStrategy.supports(parameter.nested().getNestedParameterType()));
}
@@ -56,14 +56,14 @@ public class PaginationRequestMethodArgumentResolver
implements HandlerMethod
Integer count = environment.getArgument(forward ? "first" : "last");
String cursor = environment.getArgument(forward ? "after" : "before");
P position = (cursor != null ? this.cursorStrategy.fromCursor(cursor) : null);
- return createRequest(position, count, forward);
+ return createSubrange(position, count, forward);
}
/**
- * Create the {@code PaginationRequest} instance.
+ * Allows subclasses to create an extension of {@link Subrange}.
*/
- protected PaginationRequest
createRequest(@Nullable P position, @Nullable Integer size, boolean forward) {
- return new PaginationRequest<>(position, size, forward);
+ protected Subrange
createSubrange(@Nullable P pos, @Nullable Integer size, boolean forward) {
+ return new Subrange<>(pos, size, forward);
}
}
diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/PaginationRequest.java b/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/Subrange.java
similarity index 58%
rename from spring-graphql/src/main/java/org/springframework/graphql/data/pagination/PaginationRequest.java
rename to spring-graphql/src/main/java/org/springframework/graphql/data/pagination/Subrange.java
index fdc7820d..6dbfc2a7 100644
--- a/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/PaginationRequest.java
+++ b/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/Subrange.java
@@ -22,12 +22,13 @@ import java.util.Optional;
import org.springframework.lang.Nullable;
/**
- * Container for a pagination request.
+ * Container for parameters that limit result elements to a subrange including a
+ * relative position, number of elements, and direction.
*
* @author Rossen Stoyanchev
* @since 1.2
*/
-public class PaginationRequest
{
+public class Subrange
{
@Nullable
private final P position;
@@ -39,9 +40,9 @@ public class PaginationRequest
{
/**
- * Constructor with the position, count, and direction.
+ * Constructor with the relative position, count, and direction.
*/
- public PaginationRequest(@Nullable P position, @Nullable Integer count, boolean forward) {
+ public Subrange(@Nullable P position, @Nullable Integer count, boolean forward) {
this.position = position;
this.forward = forward;
this.count = count;
@@ -49,16 +50,16 @@ public class PaginationRequest
{
/**
- * The position of an element relative to which to paginate, decoded from a
- * String cursor, e.g. the "before" and "after" arguments from the GraphQL
- * Cursor connection spec.
+ * The position of the result element the subrange is relative to. This is
+ * decoded from the "before" or "after" input arguments from the GraphQL
+ * Cursor connection spec via {@link CursorStrategy}.
*/
public Optional
position() {
return Optional.ofNullable(this.position);
}
/**
- * The number of elements requested, e.g. "first" and "last" N elements
+ * The number of elements in the subrange based on the "first" and "last"
* arguments from the GraphQL Cursor connection spec.
*/
public Optional count() {
@@ -66,12 +67,11 @@ public class PaginationRequest {
}
/**
- * Whether forward or backward pagination is requested, e.g. depending on
- * whether "fist" or "last" N elements was sent.
- *
Note: This value may not reflect the one originally
- * sent by the client. For example, for backward pagination, an offset cursor
- * may be adjusted down by the number of requested elements, turning into
- * forward pagination.
+ * Whether the subrange is forward or backward from ths position, depending
+ * on whether the argument sent "fist" or "last".
+ *
Note: The direction may not always match the original
+ * value. For backward pagination, for example, an offset cursor could be
+ * adjusted down by the count of elements, switching backward to forward.
*/
public boolean forward() {
return this.forward;
diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/query/ScrollRequest.java b/spring-graphql/src/main/java/org/springframework/graphql/data/query/ScrollSubrange.java
similarity index 54%
rename from spring-graphql/src/main/java/org/springframework/graphql/data/query/ScrollRequest.java
rename to spring-graphql/src/main/java/org/springframework/graphql/data/query/ScrollSubrange.java
index d66fd6b7..01488c66 100644
--- a/spring-graphql/src/main/java/org/springframework/graphql/data/query/ScrollRequest.java
+++ b/spring-graphql/src/main/java/org/springframework/graphql/data/query/ScrollSubrange.java
@@ -23,43 +23,41 @@ import org.springframework.data.domain.KeysetScrollPosition;
import org.springframework.data.domain.KeysetScrollPosition.Direction;
import org.springframework.data.domain.OffsetScrollPosition;
import org.springframework.data.domain.ScrollPosition;
-import org.springframework.graphql.data.pagination.PaginationRequest;
+import org.springframework.graphql.data.pagination.Subrange;
import org.springframework.lang.Nullable;
/**
- * Container for pagination request with a {@link ScrollPosition} cursor.
+ * Container for parameters that limit result elements to a subrange including a
+ * relative {@link ScrollPosition}, number of elements, and direction.
*
- *
An {@link OffsetScrollPosition} is always used for forward pagination.
- * When backward pagination is requested, the offset is adjusted down by the
- * requested count, thus turning it into forward pagination.
+ *
For backward pagination, the offset of an {@link OffsetScrollPosition}
+ * is adjusted to point to the first item in the range by subtracting the count
+ * from it. Hence, for {@code OffsetScrollPosition} {@link #forward()} is
+ * always {@code true}.
*
* @author Rossen Stoyanchev
* @since 1.2
*/
-public final class ScrollRequest extends PaginationRequest {
+public final class ScrollSubrange extends Subrange {
- public ScrollRequest(@Nullable ScrollPosition position, @Nullable Integer count, boolean forward) {
- super(initPosition(position, count, forward), count,
- (position instanceof OffsetScrollPosition || forward));
+ public ScrollSubrange(@Nullable ScrollPosition pos, @Nullable Integer count, boolean forward) {
+ super(initPosition(pos, count, forward), count, (pos instanceof OffsetScrollPosition || forward));
}
@Nullable
- private static ScrollPosition initPosition(
- @Nullable ScrollPosition position, @Nullable Integer count, boolean forward) {
-
+ private static ScrollPosition initPosition(@Nullable ScrollPosition pos, @Nullable Integer count, boolean forward) {
if (!forward) {
- if (position instanceof OffsetScrollPosition offsetPosition && count != null) {
+ if (pos instanceof OffsetScrollPosition offsetPosition && count != null) {
long offset = offsetPosition.getOffset();
return OffsetScrollPosition.of(offset > count ? offset - count : 0);
}
- else if (position instanceof KeysetScrollPosition keysetPosition) {
+ else if (pos instanceof KeysetScrollPosition keysetPosition) {
Map keys = keysetPosition.getKeys();
- position = KeysetScrollPosition.of(keys, Direction.Backward);
+ pos = KeysetScrollPosition.of(keys, Direction.Backward);
}
}
-
- return position;
+ return pos;
}
}
diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingPaginationTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingPaginationTests.java
index 19d95f37..e912eaee 100644
--- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingPaginationTests.java
+++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingPaginationTests.java
@@ -33,7 +33,7 @@ import org.springframework.graphql.TestExecutionRequest;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.graphql.data.pagination.ConnectionFieldTypeVisitor;
import org.springframework.graphql.data.query.ScrollPositionCursorStrategy;
-import org.springframework.graphql.data.query.ScrollRequest;
+import org.springframework.graphql.data.query.ScrollSubrange;
import org.springframework.graphql.data.query.WindowConnectionAdapter;
import org.springframework.graphql.execution.ConnectionTypeGenerator;
import org.springframework.stereotype.Controller;
@@ -120,7 +120,7 @@ public class SchemaMappingPaginationTests {
AnnotatedControllerConfigurer configurer = new AnnotatedControllerConfigurer();
configurer.setApplicationContext(context);
- GraphQlSetup setup = GraphQlSetup.schemaContent(this.SCHEMA).runtimeWiring(configurer);
+ GraphQlSetup setup = GraphQlSetup.schemaContent(SCHEMA).runtimeWiring(configurer);
consumer.accept(configurer, setup);
configurer.afterPropertiesSet();
@@ -134,9 +134,9 @@ public class SchemaMappingPaginationTests {
private static class BookController {
@QueryMapping
- public Window books(ScrollRequest request) {
- int offset = (int) ((OffsetScrollPosition) request.position().get()).getOffset();
- int count = request.count().get();
+ public Window books(ScrollSubrange subrange) {
+ int offset = (int) ((OffsetScrollPosition) subrange.position().orElse(OffsetScrollPosition.initial())).getOffset();
+ int count = subrange.count().orElse(5);
List books = BookSource.books().subList(offset, offset + count);
return Window.from(books, OffsetScrollPosition::of);
}
diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/PaginationRequestMethodArgumentResolverTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SubrangeMethodArgumentResolverTests.java
similarity index 76%
rename from spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/PaginationRequestMethodArgumentResolverTests.java
rename to spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SubrangeMethodArgumentResolverTests.java
index 98abfe43..c71bcf3c 100644
--- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/PaginationRequestMethodArgumentResolverTests.java
+++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SubrangeMethodArgumentResolverTests.java
@@ -27,29 +27,29 @@ import org.springframework.data.domain.Window;
import org.springframework.graphql.Book;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.graphql.data.pagination.CursorStrategy;
-import org.springframework.graphql.data.pagination.PaginationRequest;
+import org.springframework.graphql.data.pagination.Subrange;
import org.springframework.stereotype.Controller;
import static org.assertj.core.api.Assertions.assertThat;
/**
- * Unit tests for {@link PaginationRequestMethodArgumentResolver}.
+ * Unit tests for {@link SubrangeMethodArgumentResolver}.
* @author Rossen Stoyanchev
*/
-public class PaginationRequestMethodArgumentResolverTests extends ArgumentResolverTestSupport {
+public class SubrangeMethodArgumentResolverTests extends ArgumentResolverTestSupport {
- private final PaginationRequestMethodArgumentResolver resolver =
- new PaginationRequestMethodArgumentResolver<>(new MyPositionCursorStrategy());
+ private final SubrangeMethodArgumentResolver resolver =
+ new SubrangeMethodArgumentResolver<>(new MyPositionCursorStrategy());
private final MethodParameter param =
- methodParam(BookController.class, "getBooks", PaginationRequest.class);
+ methodParam(BookController.class, "getBooks", Subrange.class);
@Test
void supports() {
assertThat(this.resolver.supportsParameter(this.param)).isTrue();
- MethodParameter param = methodParam(BookController.class, "getBooksWithUnknownPosition", PaginationRequest.class);
+ MethodParameter param = methodParam(BookController.class, "getBooksWithUnknownPosition", Subrange.class);
assertThat(this.resolver.supportsParameter(param)).isFalse();
}
@@ -74,10 +74,10 @@ public class PaginationRequestMethodArgumentResolverTests extends ArgumentResolv
}
private static void testRequest(int count, int index, Object result, boolean forward) {
- PaginationRequest request = (PaginationRequest) result;
- assertThat(request.position().get().index()).isEqualTo(index);
- assertThat(request.count().get()).isEqualTo(count);
- assertThat(request.forward()).isEqualTo(forward);
+ Subrange subrange = (Subrange) result;
+ assertThat(subrange.position().get().index()).isEqualTo(index);
+ assertThat(subrange.count().get()).isEqualTo(count);
+ assertThat(subrange.forward()).isEqualTo(forward);
}
private static DataFetchingEnvironment environment(Map arguments) {
@@ -90,12 +90,12 @@ public class PaginationRequestMethodArgumentResolverTests extends ArgumentResolv
private static class BookController {
@QueryMapping
- public Window getBooks(PaginationRequest request) {
+ public Window getBooks(Subrange subrange) {
return null;
}
@QueryMapping
- public Window getBooksWithUnknownPosition(PaginationRequest request) {
+ public Window getBooksWithUnknownPosition(Subrange subrange) {
return null;
}
diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/query/ScrollRequestTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/query/ScrollSubrangeTests.java
similarity index 56%
rename from spring-graphql/src/test/java/org/springframework/graphql/data/query/ScrollRequestTests.java
rename to spring-graphql/src/test/java/org/springframework/graphql/data/query/ScrollSubrangeTests.java
index d260b12a..308d41de 100644
--- a/spring-graphql/src/test/java/org/springframework/graphql/data/query/ScrollRequestTests.java
+++ b/spring-graphql/src/test/java/org/springframework/graphql/data/query/ScrollSubrangeTests.java
@@ -33,22 +33,22 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Rossen Stoyanchev
*/
-public class ScrollRequestTests {
+public class ScrollSubrangeTests {
@Test
void offset() {
OffsetScrollPosition position = OffsetScrollPosition.of(30);
int count = 10;
- ScrollRequest request = new ScrollRequest(position, count, true);
- assertThat(((OffsetScrollPosition) request.position().get())).isEqualTo(position);
- assertThat(request.count().get()).isEqualTo(count);
- assertThat(request.forward()).isTrue();
+ ScrollSubrange subrange = new ScrollSubrange(position, count, true);
+ assertThat(((OffsetScrollPosition) subrange.position().get())).isEqualTo(position);
+ assertThat(subrange.count().get()).isEqualTo(count);
+ assertThat(subrange.forward()).isTrue();
- request = new ScrollRequest(position, count, false);
- assertThat(((OffsetScrollPosition) request.position().get()).getOffset()).isEqualTo(20);
- assertThat(request.count().get()).isEqualTo(count);
- assertThat(request.forward()).isTrue();
+ subrange = new ScrollSubrange(position, count, false);
+ assertThat(((OffsetScrollPosition) subrange.position().get()).getOffset()).isEqualTo(20);
+ assertThat(subrange.count().get()).isEqualTo(count);
+ assertThat(subrange.forward()).isTrue();
}
@Test
@@ -61,38 +61,38 @@ public class ScrollRequestTests {
ScrollPosition position = KeysetScrollPosition.of(keys);
int count = 10;
- ScrollRequest request = new ScrollRequest(position, count, true);
- KeysetScrollPosition actualPosition = (KeysetScrollPosition) request.position().get();
+ ScrollSubrange subrange = new ScrollSubrange(position, count, true);
+ KeysetScrollPosition actualPosition = (KeysetScrollPosition) subrange.position().get();
assertThat(actualPosition.getKeys()).isEqualTo(keys);
assertThat(actualPosition.getDirection()).isEqualTo(Direction.Forward);
- assertThat(request.count().get()).isEqualTo(count);
- assertThat(request.forward()).isTrue();
+ assertThat(subrange.count().get()).isEqualTo(count);
+ assertThat(subrange.forward()).isTrue();
- request = new ScrollRequest(position, count, false);
- actualPosition = (KeysetScrollPosition) request.position().get();
+ subrange = new ScrollSubrange(position, count, false);
+ actualPosition = (KeysetScrollPosition) subrange.position().get();
assertThat(actualPosition.getKeys()).isEqualTo(keys);
assertThat(actualPosition.getDirection()).isEqualTo(Direction.Backward);
- assertThat(request.count().get()).isEqualTo(count);
- assertThat(request.forward()).isFalse();
+ assertThat(subrange.count().get()).isEqualTo(count);
+ assertThat(subrange.forward()).isFalse();
}
@Test
void nullInput() {
- ScrollRequest request = new ScrollRequest(null, null, true);
+ ScrollSubrange subrange = new ScrollSubrange(null, null, true);
- assertThat(request.position()).isNotPresent();
- assertThat(request.count()).isNotPresent();
- assertThat(request.forward()).isTrue();
+ assertThat(subrange.position()).isNotPresent();
+ assertThat(subrange.count()).isNotPresent();
+ assertThat(subrange.forward()).isTrue();
}
@Test
void offsetBackwardPaginationNullSize() {
OffsetScrollPosition position = OffsetScrollPosition.of(30);
- ScrollRequest request = new ScrollRequest(position, null, false);
+ ScrollSubrange subrange = new ScrollSubrange(position, null, false);
- assertThat(((OffsetScrollPosition) request.position().get())).isEqualTo(position);
- assertThat(request.count()).isNotPresent();
- assertThat(request.forward()).isTrue();
+ assertThat(((OffsetScrollPosition) subrange.position().get())).isEqualTo(position);
+ assertThat(subrange.count()).isNotPresent();
+ assertThat(subrange.forward()).isTrue();
}
}