Skip to content

Commit 1297e68

Browse files
authored
fix(GH253): Support enable/disable default max result size query pagination (#254)
1 parent 7cc3e57 commit 1297e68

File tree

4 files changed

+107
-55
lines changed

4 files changed

+107
-55
lines changed

graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaExecutorContext.java

+9-5
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,7 @@ private GraphQLJpaExecutorContext(Builder builder) {
6262
@Override
6363
public ExecutionInput.Builder newExecutionInput() {
6464
DataLoaderRegistry dataLoaderRegistry = newDataLoaderRegistry();
65-
66-
GraphQLContext context = graphqlContext.get();
67-
68-
context.put("dataLoaderRegistry", dataLoaderRegistry);
65+
GraphQLContext context = newGraphQLContext(dataLoaderRegistry);
6966

7067
return executionInputFactory.create()
7168
.dataLoaderRegistry(dataLoaderRegistry)
@@ -80,6 +77,14 @@ public GraphQL.Builder newGraphQL() {
8077
.instrumentation(instrumentation);
8178
}
8279

80+
public GraphQLContext newGraphQLContext(DataLoaderRegistry dataLoaderRegistry) {
81+
GraphQLContext context = graphqlContext.get();
82+
83+
context.put("dataLoaderRegistry", dataLoaderRegistry);
84+
85+
return context;
86+
}
87+
8388
public DataLoaderRegistry newDataLoaderRegistry() {
8489
return dataLoaderRegistry.get();
8590
}
@@ -97,7 +102,6 @@ public Instrumentation newIstrumentation() {
97102
instrumentation.get());
98103

99104
return new ChainedInstrumentation(list);
100-
101105
}
102106

103107
@Override

graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaQueryDataFetcher.java

+39-22
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import static com.introproventures.graphql.jpa.query.support.GraphQLSupport.getSelectionField;
2424
import static com.introproventures.graphql.jpa.query.support.GraphQLSupport.searchByFieldName;
2525

26+
import java.util.Collections;
2627
import java.util.List;
2728
import java.util.Optional;
2829

@@ -35,31 +36,33 @@
3536
import graphql.schema.DataFetchingEnvironment;
3637

3738
/**
38-
* JPA Query DataFetcher implementation that fetches entities with page and where criteria expressions
39-
*
39+
* JPA Query DataFetcher implementation that fetches entities with page and where criteria expressions
40+
*
4041
* @author Igor Dianov
4142
*
4243
*/
4344
class GraphQLJpaQueryDataFetcher implements DataFetcher<PagedResult<Object>> {
44-
45+
4546
private final static Logger logger = LoggerFactory.getLogger(GraphQLJpaQueryDataFetcher.class);
4647

4748
private final int defaultMaxResults;
4849
private final int defaultPageLimitSize;
50+
private final boolean enableDefaultMaxResults;
4951
private final GraphQLJpaQueryFactory queryFactory;
5052

5153
private GraphQLJpaQueryDataFetcher(Builder builder) {
5254
this.queryFactory = builder.queryFactory;
5355
this.defaultMaxResults = builder.defaultMaxResults;
5456
this.defaultPageLimitSize = builder.defaultPageLimitSize;
57+
this.enableDefaultMaxResults = builder.enableDefaultMaxResults;
5558
}
56-
59+
5760
@Override
5861
public PagedResult<Object> get(DataFetchingEnvironment environment) {
5962
final Field rootNode = environment.getField();
6063
final Optional<Argument> pageArgument = getPageArgument(environment.getField());
6164
final PageArgument page = extractPageArgument(environment, pageArgument, defaultPageLimitSize);
62-
65+
6366
// Let's see which fields we're requesting
6467
Optional<Field> pagesSelection = getSelectionField(rootNode, PAGE_PAGES_PARAM_NAME);
6568
Optional<Field> totalSelection = getSelectionField(rootNode, PAGE_TOTAL_PARAM_NAME);
@@ -72,32 +75,32 @@ public PagedResult<Object> get(DataFetchingEnvironment environment) {
7275
.withOffset(firstResult)
7376
.withLimit(maxResults);
7477
if (recordsSelection.isPresent()) {
75-
final List<Object> keys = queryFactory.queryKeys(environment,
76-
firstResult,
77-
maxResults);
78-
if(!keys.isEmpty()) {
79-
final List<Object> resultList = queryFactory.queryResultList(environment,
80-
maxResults,
81-
keys);
82-
pagedResult.withSelect(resultList);
78+
List<Object> keys = Collections.emptyList();
79+
80+
if (pageArgument.isPresent() || enableDefaultMaxResults) {
81+
keys = queryFactory.queryKeys(environment, firstResult, maxResults);
8382
}
83+
84+
final List<Object> resultList = queryFactory.queryResultList(environment,
85+
maxResults,
86+
keys);
87+
pagedResult.withSelect(resultList);
8488
}
85-
89+
8690
if (totalSelection.isPresent() || pagesSelection.isPresent()) {
87-
8891
final Long total = queryFactory.queryTotalCount(environment);
8992

9093
pagedResult.withTotal(total);
9194
}
92-
95+
9396
return pagedResult.build();
9497
}
95-
96-
98+
99+
97100
public int getDefaultMaxResults() {
98101
return defaultMaxResults;
99102
}
100-
103+
101104
public int getDefaultPageLimitSize() {
102105
return defaultPageLimitSize;
103106
}
@@ -133,7 +136,14 @@ public interface IDefaultMaxResultsStage {
133136
* @param defaultMaxResults field to set
134137
* @return builder
135138
*/
136-
public IDefaultPageLimitSizeStage withDefaultMaxResults(int defaultMaxResults);
139+
public IDefaultMaxResultsStage withDefaultMaxResults(int defaultMaxResults);
140+
141+
/**
142+
* Builder method for enableDefaultMaxResults parameter.
143+
* @param enableDefaultMaxResults field to set
144+
* @return builder
145+
*/
146+
public IDefaultPageLimitSizeStage withEnableDefaultMaxResults(boolean enableDefaultMaxResults);
137147
}
138148

139149
/**
@@ -169,6 +179,7 @@ public static final class Builder implements IQueryFactoryStage, IDefaultMaxResu
169179
private GraphQLJpaQueryFactory queryFactory;
170180
private int defaultMaxResults;
171181
private int defaultPageLimitSize;
182+
private boolean enableDefaultMaxResults;
172183

173184
private Builder() {
174185
}
@@ -180,7 +191,7 @@ public IDefaultMaxResultsStage withQueryFactory(GraphQLJpaQueryFactory queryFact
180191
}
181192

182193
@Override
183-
public IDefaultPageLimitSizeStage withDefaultMaxResults(int defaultMaxResults) {
194+
public IDefaultMaxResultsStage withDefaultMaxResults(int defaultMaxResults) {
184195
this.defaultMaxResults = defaultMaxResults;
185196
return this;
186197
}
@@ -195,6 +206,12 @@ public IBuildStage withDefaultPageLimitSize(int defaultPageLimitSize) {
195206
public GraphQLJpaQueryDataFetcher build() {
196207
return new GraphQLJpaQueryDataFetcher(this);
197208
}
209+
210+
@Override
211+
public IDefaultPageLimitSizeStage withEnableDefaultMaxResults(boolean enableDefaultMaxResults) {
212+
this.enableDefaultMaxResults = enableDefaultMaxResults;
213+
return this;
214+
}
198215
}
199-
}
216+
}
200217

graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaSchemaBuilder.java

+13
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ public class GraphQLJpaSchemaBuilder implements GraphQLSchemaBuilder {
129129
private int defaultMaxResults = 100;
130130
private int defaultFetchSize = 100;
131131
private int defaultPageLimitSize = 100;
132+
private boolean enableDefaultMaxResults = true;
132133

133134
private final Relay relay = new Relay();
134135

@@ -264,12 +265,14 @@ private GraphQLFieldDefinition getQueryFieldSelectDefinition(EntityType<?> entit
264265
dataFetcher = GraphQLJpaRelayDataFetcher.builder()
265266
.withQueryFactory(queryFactory)
266267
.withDefaultMaxResults(defaultMaxResults)
268+
.withEnableDefaultMaxResults(enableDefaultMaxResults)
267269
.withDefaultFirstSize(defaultPageLimitSize)
268270
.build();
269271
} else {
270272
dataFetcher = GraphQLJpaQueryDataFetcher.builder()
271273
.withQueryFactory(queryFactory)
272274
.withDefaultMaxResults(defaultMaxResults)
275+
.withEnableDefaultMaxResults(enableDefaultMaxResults)
273276
.withDefaultPageLimitSize(defaultPageLimitSize)
274277
.build();
275278
}
@@ -1426,4 +1429,14 @@ public GraphQLJpaSchemaBuilder defaultFetchSize(int defaultFetchSize) {
14261429
return this;
14271430
}
14281431

1432+
public boolean isEnableDefaultMaxResults() {
1433+
return enableDefaultMaxResults;
1434+
}
1435+
1436+
public GraphQLJpaSchemaBuilder enableDefaultMaxResults(boolean enableDefaultMaxResults) {
1437+
this.enableDefaultMaxResults = enableDefaultMaxResults;
1438+
1439+
return this;
1440+
}
1441+
14291442
}

graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/relay/GraphQLJpaRelayDataFetcher.java

+46-28
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import static com.introproventures.graphql.jpa.query.support.GraphQLSupport.getSelectionField;
44
import static com.introproventures.graphql.jpa.query.support.GraphQLSupport.searchByFieldName;
55

6+
import java.util.Collections;
67
import java.util.List;
78
import java.util.Optional;
89

@@ -11,7 +12,6 @@
1112

1213
import com.introproventures.graphql.jpa.query.schema.impl.GraphQLJpaQueryFactory;
1314
import com.introproventures.graphql.jpa.query.schema.impl.PagedResult;
14-
1515
import graphql.language.Field;
1616
import graphql.schema.DataFetcher;
1717
import graphql.schema.DataFetchingEnvironment;
@@ -26,60 +26,64 @@ public class GraphQLJpaRelayDataFetcher implements DataFetcher<Page<Object>> {
2626

2727
private final int defaultMaxResults;
2828
private final int defaultFirstSize;
29+
private final boolean enableDefaultMaxResults;
2930
private final GraphQLJpaQueryFactory queryFactory;
3031

3132
private GraphQLJpaRelayDataFetcher(Builder builder) {
3233
this.queryFactory = builder.queryFactory;
3334
this.defaultMaxResults = builder.defaultMaxResults;
3435
this.defaultFirstSize = builder.defaultFirstSize;
36+
this.enableDefaultMaxResults = builder.enableDefaultMaxResults;
3537
}
36-
38+
3739
@Override
3840
public Page<Object> get(DataFetchingEnvironment environment) throws Exception {
3941
final Field rootNode = environment.getField();
40-
42+
4143
Optional<Field> edgesSelection = searchByFieldName(rootNode, EDGES);
4244
Optional<Field> pageInfoSelection = getSelectionField(rootNode, PAGE_INFO);
43-
44-
final Integer first = Optional.<Integer> ofNullable(environment.getArgument(FIRST))
45-
.orElse(defaultFirstSize);
46-
47-
final String after = Optional.<String>ofNullable(environment.getArgument(AFTER))
48-
.orElse(new OffsetBasedCursor(0L).toConnectionCursor()
45+
Optional<Integer> firstArgument = Optional.<Integer>ofNullable(environment.getArgument(FIRST));
46+
Optional<String> afterArgument = Optional.<String>ofNullable(environment.getArgument(AFTER));
47+
48+
final Integer first = firstArgument.orElse(defaultFirstSize);
49+
50+
final String after = afterArgument.orElse(new OffsetBasedCursor(0L).toConnectionCursor()
4951
.toString());
5052

5153
final OffsetBasedCursor cursor = OffsetBasedCursor.fromCursor(after);
52-
54+
5355
final int firstResult = Integer.parseInt(Long.toString(cursor.getOffset()));
5456
final int maxResults = Integer.min(first, defaultMaxResults);
55-
57+
5658
final PagedResult.Builder<Object> pagedResult = PagedResult.builder()
5759
.withOffset(firstResult)
5860
.withLimit(maxResults);
59-
61+
6062
if (edgesSelection.isPresent()) {
61-
final List<Object> keys = queryFactory.queryKeys(environment,
62-
firstResult,
63-
maxResults);
64-
if(!keys.isEmpty()) {
65-
final List<Object> resultList = queryFactory.queryResultList(environment,
66-
maxResults,
67-
keys);
68-
pagedResult.withSelect(resultList);
63+
List<Object> keys = Collections.emptyList();
64+
65+
if (enableDefaultMaxResults || firstArgument.isPresent() || afterArgument.isPresent()) {
66+
keys = queryFactory.queryKeys(environment,
67+
firstResult,
68+
maxResults);
6969
}
70+
71+
final List<Object> resultList = queryFactory.queryResultList(environment,
72+
maxResults,
73+
keys);
74+
pagedResult.withSelect(resultList);
7075
}
71-
76+
7277
if (pageInfoSelection.isPresent()) {
73-
7478
final Long total = queryFactory.queryTotalCount(environment);
7579

7680
pagedResult.withTotal(total);
7781
}
78-
82+
7983
PagedResult<Object> result = pagedResult.build();
80-
81-
return PageFactory.createOffsetBasedPage(result.getSelect(),
82-
result.getTotal(),
84+
85+
return PageFactory.createOffsetBasedPage(result.getSelect(),
86+
result.getTotal(),
8387
result.getOffset());
8488
}
8589

@@ -114,7 +118,14 @@ public interface IDefaultMaxResultsStage {
114118
* @param defaultMaxResults field to set
115119
* @return builder
116120
*/
117-
public IDefaultFirstSizeStage withDefaultMaxResults(int defaultMaxResults);
121+
public IDefaultMaxResultsStage withDefaultMaxResults(int defaultMaxResults);
122+
123+
/**
124+
* Builder method for enableDefaultMaxResults parameter.
125+
* @param enableDefaultMaxResults field to set
126+
* @return builder
127+
*/
128+
public IDefaultFirstSizeStage withEnableDefaultMaxResults(boolean enableDefaultMaxResults);
118129
}
119130

120131
/**
@@ -150,6 +161,7 @@ public static final class Builder implements IQueryFactoryStage, IDefaultMaxResu
150161
private GraphQLJpaQueryFactory queryFactory;
151162
private int defaultMaxResults;
152163
private int defaultFirstSize;
164+
private boolean enableDefaultMaxResults;
153165

154166
private Builder() {
155167
}
@@ -161,7 +173,7 @@ public IDefaultMaxResultsStage withQueryFactory(GraphQLJpaQueryFactory queryFact
161173
}
162174

163175
@Override
164-
public IDefaultFirstSizeStage withDefaultMaxResults(int defaultMaxResults) {
176+
public IDefaultMaxResultsStage withDefaultMaxResults(int defaultMaxResults) {
165177
this.defaultMaxResults = defaultMaxResults;
166178
return this;
167179
}
@@ -176,6 +188,12 @@ public IBuildStage withDefaultFirstSize(int defaultFirstSize) {
176188
public GraphQLJpaRelayDataFetcher build() {
177189
return new GraphQLJpaRelayDataFetcher(this);
178190
}
191+
192+
@Override
193+
public IDefaultFirstSizeStage withEnableDefaultMaxResults(boolean enableDefaultMaxResults) {
194+
this.enableDefaultMaxResults = enableDefaultMaxResults;
195+
return this;
196+
}
179197
}
180198

181199
}

0 commit comments

Comments
 (0)