@@ -571,28 +571,25 @@ to send to the client.
571571[[execution.pagination]]
572572=== Pagination
573573
574- The https://relay.dev/graphql/connections.htm[GraphQL Cursor Connection specification]
574+ The GraphQL Cursor Connection https://relay.dev/graphql/connections.htm[specification]
575575defines a mechanism for efficient navigation of large result sets by returning a limited
576- subset of items at a time. Each item is assigned a unique cursor that a client can use to
577- request the next items after or the previous items before the cursor reference, as a way of
578- navigating forward or backward.
576+ set of items at a time. Each item is paired with a cursor that a client can use to request
577+ the items after or before the cursor, providing a way to navigate forward and backward.
579578
580- The spec calls this pattern "Connections", and each schema type whose name ends on
581- "Connection" is considered a _Connection Type_ and represents a paginated result set.
582- Each `Connection` contains "edges" where an `EdgeType` is a wrapper around the actual item
583- and its cursor. There is also a `PageInfo` object with flags for whether you can navigate
584- further forward and backward and the cursors of the start and end items in the set.
579+ The spec calls the pattern "Connections". A schema type whose name ends on "Connection"
580+ is considered a _Connection Type_ and represents a paginated result set. A `Connection`
581+ contains "edges" where an `Edge` is a wrapper around the actual item and its cursor.
582+ There is also a `PageInfo` to indicate whether there are more items forward and backward.
585583
586584
587- [[execution.pagination.type.definitions ]]
588- ==== Connection Type Definitions
585+ [[execution.pagination.types ]]
586+ ==== Connection Types
589587
590588`Connection` type definitions must be repeated for every type that needs pagination, adding
591- boilerplate and noise to the schema. To address this, Spring for GraphQL provides the
592- `ConnectionTypeDefinitionConfigurer` that adds these types on startup, if not already
593- present in the parsed schema files.
594-
595- That means you can declare `Connection` fields, but leave out their declaration:
589+ boilerplate and noise to the schema. Spring for GraphQL provides
590+ `ConnectionTypeDefinitionConfigurer` to generate these types on startup, if not already
591+ present in the parsed schema files. That means you can have a `Connection` field without
592+ a type declaration as follows:
596593
597594[source,graphql,indent=0,subs="verbatim,quotes"]
598595----
@@ -606,7 +603,7 @@ That means you can declare `Connection` fields, but leave out their declaration:
606603 }
607604----
608605
609- Then configure the `ConnectionTypeDefinitionConfigurer`:
606+ Configure `ConnectionTypeDefinitionConfigurer` as follows :
610607
611608[source,java,indent=0,subs="verbatim,quotes"]
612609----
@@ -615,7 +612,7 @@ GraphQlSource.schemaResourceBuilder()
615612 .typeDefinitionConfigurer(new ConnectionTypeDefinitionConfigurer)
616613----
617614
618- The following type definitions are added on startup to the schema:
615+ The following type definitions will be added to the schema on startup :
619616
620617[source,graphql,indent=0,subs="verbatim,quotes"]
621618----
@@ -637,25 +634,25 @@ The following type definitions are added on startup to the schema:
637634 }
638635----
639636
637+ The <<boot-starter>> registers `ConnectionTypeDefinitionConfigurer` by default.
638+
640639
641640[[execution.pagination.adapters]]
642- ==== Connection Adapters
641+ ==== `ConnectionAdapter`
643642
644- Once <<execution.pagination.type.definitions >> are available in the schema, you also need
643+ Once <<execution.pagination.types >> are available in the schema, you also need
645644equivalent Java types. GraphQL Java provides those, including generic `Connection` and
646- `Edge` types , as well as `PageInfo`.
645+ `Edge`, as well as a `PageInfo`.
647646
648- One option is to populate and return `Connection` directly from your controller method or
649- `DataFetcher`. However, this is boilerplate work, to wrap each item, create cursors, and
650- so on. Moreover, you may already have an underlying pagination mechanism such as when
651- using Spring Data repositories.
647+ One option is to populate a `Connection` and return it from your controller method or
648+ `DataFetcher`. However, this requires boilerplate code to create the `Connection`,
649+ creating cursors, wrapping each item as an `Edge`, and creating the `PageInfo`.
650+ Moreover, you may already have an underlying pagination mechanism such as when using
651+ Spring Data repositories.
652652
653- To make this transparent, Spring for GraphQL has a `ConnectionAdapter` contract to adapt
654- any container of items to `Connection`. This is applied through a
655- `ConnectionFieldTypeVisitor` that looks for any `Connection` field, decorates the
656- registered `DataFetcher`, and adapts its return values.
657-
658- For example:
653+ Spring for GraphQL defines the `ConnectionAdapter` contract to adapt a container of items
654+ to `Connection`. Adapters are applied through a `DataFetcher` decorator that is in turn
655+ installed through a `ConnectionFieldTypeVisitor`. You can configure it as follows:
659656
660657[source,java,indent=0,subs="verbatim,quotes"]
661658----
@@ -668,54 +665,56 @@ GraphQlSource.schemaResourceBuilder()
668665 .typeVisitors(List.of(visitor)) // <2>
669666----
670667
671- <1> Create type visitor with one or more `Connection` adapters .
668+ <1> Create type visitor with one or more ``ConnectionAdapter``s .
672669<2> Resister the type visitor.
673670
674- There are <<data.scroll.sort,built-in>> ``ConnectionAdapter``s for the Spring Data
675- pagination types `Window` and `Slice`. You can also create your own custom adapter.
676-
677- `ConnectionAdapter` implementations rely on a <<execution.pagination.cursor. strategy>> to create a cursor for
678- each returned item. , and the same strategy is also used subsequently to decode the cursor
679- to support the <<controllers.schema-mapping.subrange>> controller method argument .
671+ There are <<data.scroll.sort,built-in>> ``ConnectionAdapter``s for Spring Data's
672+ `Window` and `Slice`. You can also create your own custom adapter. `ConnectionAdapter`
673+ implementations rely on a <<execution.pagination.cursor.strategy>> to
674+ create cursors for returned items. The same strategy is also used to support the
675+ <<controllers.schema-mapping.subrange>> controller method argument that contains
676+ pagination input .
680677
681678
682679[[execution.pagination.cursor.strategy]]
683- ==== Cursor Strategy
680+ ==== `CursorStrategy`
684681
685682`CursorStrategy` is a contract to create a String cursor for an item to reflect its
686683position within a large result set, e.g. based on an offset or key set.
687- <<execution.pagination.adapters>> use this to create a cursor for returned items.
684+ <<execution.pagination.adapters>> implementations use this to create cursors for returned
685+ items.
688686
689- The strategy also helps to decode a cursor back to an item position. For this to work,
690- you need to declare a `CursorStrategy` bean, and ensure that annotated controllers are
691- <<controllers-declaration, enabled>> .
687+ The strategy also supports the <<controllers.schema-mapping.subrange>> controller
688+ method argument. For this to work, you need to declare a `CursorStrategy` bean, and also
689+ ensure that annotated controllers are <<controllers-declaration, configured>> for use .
692690
693691`CursorEncoder` is a related, supporting strategy to encode and decode cursors to make
694692them opaque to clients. `EncodingCursorStrategy` combines `CursorStrategy` with a
695- `CursorEncoder`. There is a built-in `Base64CursorEncoder`.
693+ `CursorEncoder`. You can use `Base64CursorEncoder`, `NoOpEncoder` or create your own .
696694
697- There is a <<data.scroll.sort,built-in>> `CursorStrategy` for the Spring Data `ScrollPosition`.
695+ There is a <<data.scroll.sort,built-in>> `CursorStrategy` for the Spring Data
696+ `ScrollPosition`. The <<boot-starter>> registers a `ScrollPositionCursorStrategy` with
697+ `Base64Encoder` when Spring Data is present.
698698
699699
700700[[execution.pagination.arguments]]
701701==== Arguments
702702
703703Controller methods can declare a <<controllers.schema-mapping.subrange>>, or a
704- `ScrollSubange` method argument, to handle requests for forward or backward pagination.
705- The method argument resolver is configured for use when a
706- <<execution.pagination.cursor.strategy>> bean is declared in Spring configuration.
704+ `ScrollSubange` method argument when Spring Data is present, for pagination requests .
705+ The argument resolver is added when a <<execution.pagination.cursor.strategy>> bean is
706+ present in Spring configuration.
707707
708708
709709[[execution.pagination.sort.strategy]]
710710==== Sort
711711
712- Pagination depends on a stable sort order. There is no standard for how to declare sort
713- related GraphQL input arguments. You can keep it as an internal detail with a default
714- sort, or if it you need to expose it, then you'll need to extract the sort details from
715- GraphQL arguments.
712+ There is no standard way to provide sort information in a GraphQL request. However,
713+ pagination depends on a stable sort order. You can use a default order or extract, and
714+ keep it as an internal detail, or extract sort details from GraphQL arguments.
716715
717- There is partial, <<data.scroll.sort,built-in>> support for to create a Spring Data
718- `Sort`, with the help of a `SortStrategy`, and inject that into a controller method .
716+ There is <<data.scroll.sort,built-in>> support for Spring Data's `Sort` as a controller
717+ method argument. For this to work, you need to have a `SortStrategy` bean .
719718
720719
721720[[execution.batching]]
0 commit comments