Skip to content

Commit 1d32393

Browse files
committed
Flexible creation of graphql.relay.Connection
Closes gh-1343
1 parent 509ec0b commit 1d32393

File tree

3 files changed

+38
-7
lines changed

3 files changed

+38
-7
lines changed

spring-graphql/src/main/java/org/springframework/graphql/data/pagination/CompositeConnectionAdapter.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,17 @@
2424
import org.springframework.util.Assert;
2525

2626
/**
27-
* {@link ConnectionAdapter} that contains a list of others adapter, looks for
28-
* the first one that supports a given Object container type, and delegates to it.
27+
* {@link ConnectionAdapter} that wraps a list of other adapters, and delegates
28+
* to the one that supports a given type of Object container.
2929
*
3030
* @author Rossen Stoyanchev
3131
*/
32-
final class CompositeConnectionAdapter implements ConnectionAdapter {
32+
public class CompositeConnectionAdapter implements ConnectionAdapter {
3333

3434
private final List<ConnectionAdapter> adapters;
3535

3636

37-
CompositeConnectionAdapter(List<ConnectionAdapter> adapters) {
37+
public CompositeConnectionAdapter(List<ConnectionAdapter> adapters) {
3838
Assert.notEmpty(adapters, "ConnectionAdapter's are required");
3939
this.adapters = adapters;
4040
}

spring-graphql/src/main/java/org/springframework/graphql/data/pagination/ConnectionAdapter.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,12 @@
1919
import java.util.Collection;
2020
import java.util.List;
2121

22+
import graphql.relay.DefaultConnection;
23+
import graphql.relay.Edge;
24+
import graphql.relay.PageInfo;
25+
2226
/**
23-
* Contract to adapt a container object for a window of elements from a larger
27+
* Contract to adapt any representation of a subset of elements from a larger
2428
* result set to {@link graphql.relay.Connection}.
2529
*
2630
* @author Rossen Stoyanchev
@@ -60,6 +64,22 @@ public interface ConnectionAdapter {
6064
*/
6165
String cursorAt(Object container, int index);
6266

67+
/**
68+
* Create the {@link graphql.relay.Connection}.
69+
* <p>The relay spec says that a Connection may have additional fields
70+
* related to the connection, and this method allows adapter
71+
* implementations to create such an extended Connection.
72+
* <p>By default, {@link DefaultConnection} is created.
73+
* @param container the underlying container of elements
74+
* @param edges the adapted edges to use
75+
* @param pageInfo the page info for the connection
76+
* @param <T> the type edge node
77+
* @since 2.0
78+
*/
79+
default <T> Object createConnection(Object container, List<Edge<T>> edges, PageInfo pageInfo) {
80+
return new DefaultConnection<>(edges, pageInfo);
81+
}
82+
6383

6484
/**
6585
* Create a composite {@link ConnectionAdapter} that checks which adapter

spring-graphql/src/main/java/org/springframework/graphql/data/pagination/ConnectionFieldTypeVisitor.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,18 @@ private static boolean isConnectionField(GraphQLFieldDefinition field) {
182182
*/
183183
public static ConnectionFieldTypeVisitor create(List<ConnectionAdapter> adapters) {
184184
Assert.notEmpty(adapters, "Expected at least one ConnectionAdapter");
185-
return new ConnectionFieldTypeVisitor(ConnectionAdapter.from(adapters));
185+
return create(ConnectionAdapter.from(adapters));
186+
}
187+
188+
/**
189+
* Variant of {@link #create(List)} with a single adapter. This may be used
190+
* with a custom {@link CompositeConnectionAdapter}.
191+
* @param adapter the adapter to use
192+
* @return the type visitor
193+
* @since 2.0
194+
*/
195+
public static ConnectionFieldTypeVisitor create(ConnectionAdapter adapter) {
196+
return new ConnectionFieldTypeVisitor(adapter);
186197
}
187198

188199

@@ -266,7 +277,7 @@ private Object adaptDataFetcherResult(Object value) {
266277
edges.get(0).getCursor(), edges.get(edges.size() - 1).getCursor(),
267278
this.adapter.hasPrevious(container), this.adapter.hasNext(container));
268279

269-
return new DefaultConnection<>(edges, pageInfo);
280+
return this.adapter.createConnection(container, edges, pageInfo);
270281
}
271282

272283
private boolean isConnectionTypeNullable() {

0 commit comments

Comments
 (0)