Skip to content

Commit de5fb85

Browse files
authored
feat: async pagination support with meta-data for each page (#130)
1 parent 502d6b5 commit de5fb85

26 files changed

Lines changed: 2248 additions & 952 deletions

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ Core lib's Maven group ID is `io.apimatic`, and its artifact ID is `core`.
5454
| [`CoreApiException`](./src/main/java/io/apimatic/core/types/CoreApiException.java) | This is the base class for all exceptions that represent an error response from the server |
5555
| [`MultipartFileWrapper`](./src/main/java/io/apimatic/core/types/http/request/MultipartFileWrapper.java) | To wrap file and headers to be sent as part of a multipart request |
5656
| [`MultipartWrapper`](./src/main/java/io/apimatic/core/types/http/request/MultipartWrapper.java) | To wrap byteArray and headers to be sent as part of a multipart request |
57+
| [`PaginatedData`](./src/main/java/io/apimatic/core/types/pagination/PaginatedData.java) | To provide pagination functionality for both synchronous and asynchronous pagination types |
58+
| [`PageWrapper`](./src/main/java/io/apimatic/core/types/pagination/PageWrapper.java) | To wrap a single page along with its items and meta-data in the paginated data |
59+
| [`CursorPagination`](./src/main/java/io/apimatic/core/types/pagination/CursorPagination.java) | Provides cursor based pagination strategy |
60+
| [`LinkPagination`](./src/main/java/io/apimatic/core/types/pagination/LinkPagination.java) | Provides link based pagination strategy |
61+
| [`OffsetPagination`](./src/main/java/io/apimatic/core/types/pagination/OffsetPagination.java) | Provides offset based pagination strategy |
62+
| [`PagePagination`](./src/main/java/io/apimatic/core/types/pagination/PagePagination.java) | Provides page based pagination strategy |
5763
| [`CoreHelper`](./src/main/java/io/apimatic/core/utilities/CoreHelper.java) | This is a Helper class with commonly used utilities for the SDK |
5864
| [`DateHelper`](./src/main/java/io/apimatic/core/utilities/DateHelper.java) | This is a utility class for LocalDate operations |
5965
| [`LocalDateTimeHelper`](./src/main/java/io/apimatic/core/utilities/LocalDateTimeHelper.java) | This is a utility class for LocalDateTime operations |
@@ -75,6 +81,7 @@ Core lib's Maven group ID is `io.apimatic`, and its artifact ID is `core`.
7581
| [`RequestExecutor`](./src/main/java/io/apimatic/core/request/async/RequestExecutor.java) | A Request executor that executes request and returns the response asynchronously |
7682
| [`RequestSupplier`](./src/main/java/io/apimatic/core/request/async/RequestSupplier.java) | A Request Supplier that supplies the request |
7783
| [`TypeCombinator`](./src/main/java/io/apimatic/core/annotations/TypeCombinator.java) | This is a container of annotations for oneOf/anyOf cases |
84+
| [`PaginationStrategy`](./src/main/java/io/apimatic/core/types/pagination/PaginationStrategy.java) | Provides the functionality to apply pagination parameters and return new request |
7885

7986
## Links
8087

src/main/java/io/apimatic/core/ApiCall.java

Lines changed: 58 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
package io.apimatic.core;
22

33
import java.io.IOException;
4+
import java.util.List;
45
import java.util.concurrent.CompletableFuture;
56
import java.util.function.Consumer;
7+
import java.util.function.Function;
68

79
import io.apimatic.core.configurations.http.request.EndpointConfiguration;
810
import io.apimatic.core.logger.SdkLoggerFactory;
911
import io.apimatic.core.request.async.AsyncExecutor;
1012
import io.apimatic.core.types.CoreApiException;
13+
import io.apimatic.core.types.pagination.PageWrapper;
14+
import io.apimatic.core.types.pagination.PaginatedData;
15+
import io.apimatic.core.types.pagination.PaginationStrategy;
1116
import io.apimatic.coreinterfaces.http.Context;
1217
import io.apimatic.coreinterfaces.http.request.Request;
1318
import io.apimatic.coreinterfaces.http.response.Response;
@@ -46,6 +51,8 @@ public final class ApiCall<ResponseType, ExceptionType extends CoreApiException>
4651
*/
4752
private final ApiLogger apiLogger;
4853

54+
private Response response;
55+
4956

5057
/**
5158
* ApiCall constructor.
@@ -65,6 +72,35 @@ private ApiCall(final GlobalConfiguration globalConfig,
6572
this.apiLogger = SdkLoggerFactory.getLogger(globalConfig.getLoggingConfiguration());
6673
}
6774

75+
/**
76+
* Prepare this ApiCall for pagination.
77+
* @param <T> Return type for the paginated data.
78+
* @param <I> Type of items in pages.
79+
* @param <P> Type of pages.
80+
* @param converter Converts the PaginatedData into the instance of type T.
81+
* @param responseToPage Converts the PageWrapper into the instance of type P.
82+
* @param responseToItems Extract list of items of type I from response.
83+
* @param strategies List of applicable pagination strategies.
84+
* @return Converted paginated data into type T
85+
*/
86+
public <T, I, P> T paginate(
87+
Function<PaginatedData<I, P, ResponseType, ExceptionType>, T> converter,
88+
Function<PageWrapper<I, ResponseType>, P> responseToPage,
89+
Function<ResponseType, List<I>> responseToItems,
90+
PaginationStrategy... strategies) {
91+
return converter.apply(new PaginatedData<I, P, ResponseType, ExceptionType>(
92+
this, responseToPage, responseToItems, strategies
93+
));
94+
}
95+
96+
public Response getResponse() {
97+
return response;
98+
}
99+
100+
public HttpRequest.Builder getRequestBuilder() {
101+
return requestBuilder.copy();
102+
}
103+
68104
/**
69105
* Execute the ApiCall and returns the expected response.
70106
* @return instance of ResponseType.
@@ -74,13 +110,13 @@ private ApiCall(final GlobalConfiguration globalConfig,
74110
public ResponseType execute() throws IOException, ExceptionType {
75111
Request request = requestBuilder.build(globalConfig);
76112
apiLogger.logRequest(request);
77-
Response response = globalConfig.getHttpClient().execute(request, endpointConfiguration);
113+
response = globalConfig.getHttpClient().execute(request, endpointConfiguration);
78114
apiLogger.logResponse(response);
79115

80116
Context context = globalConfig.getCompatibilityFactory()
81117
.createHttpContext(request, response);
82118

83-
return responseHandler.handle(context, endpointConfiguration, globalConfig, requestBuilder);
119+
return responseHandler.handle(context, endpointConfiguration, globalConfig);
84120
}
85121

86122
/**
@@ -91,14 +127,29 @@ public CompletableFuture<ResponseType> executeAsync() {
91127
return AsyncExecutor.makeHttpCallAsync(() -> requestBuilder.build(globalConfig),
92128
request -> globalConfig.getHttpClient()
93129
.executeAsync(request, endpointConfiguration),
94-
(request, response) -> {
130+
(req, res) -> {
131+
this.response = res;
95132
Context context = globalConfig.getCompatibilityFactory()
96-
.createHttpContext(request, response);
97-
return responseHandler.handle(context, endpointConfiguration, globalConfig,
98-
requestBuilder);
133+
.createHttpContext(req, res);
134+
return responseHandler.handle(context, endpointConfiguration, globalConfig);
99135
}, apiLogger);
100136
}
101137

138+
/**
139+
* Converts this ApiCall instance to its builder.
140+
* @return ApiCall.Builder that can create a copy of this instance.
141+
*/
142+
public Builder<ResponseType, ExceptionType> toBuilder() {
143+
Builder<ResponseType, ExceptionType> builder = new Builder<ResponseType, ExceptionType>();
144+
145+
builder.globalConfig = globalConfig;
146+
builder.endpointConfigurationBuilder = endpointConfiguration.toBuilder();
147+
builder.responseHandlerBuilder = responseHandler.toBuilder();
148+
builder.requestBuilder = requestBuilder.copy();
149+
150+
return builder;
151+
}
152+
102153
/**
103154
* Builder class for the {@link ApiCall} class.
104155
* @param <ResponseType> resource from server.
@@ -179,22 +230,11 @@ public Builder<ResponseType, ExceptionType> endpointConfiguration(
179230
return this;
180231
}
181232

182-
/**
183-
* @param builder endpointConfigurationBuilder {@link EndpointConfiguration.Builder}.
184-
* @return {@link ApiCall.Builder}.
185-
*/
186-
public Builder<ResponseType, ExceptionType> endpointConfiguration(
187-
EndpointConfiguration.Builder builder) {
188-
endpointConfigurationBuilder = builder;
189-
return this;
190-
}
191-
192233
/**
193234
* build the {@link ApiCall}.
194235
* @return the instance of {@link ApiCall}.
195-
* @throws IOException Signals that an I/O exception of some sort has occurred.
196236
*/
197-
public ApiCall<ResponseType, ExceptionType> build() throws IOException {
237+
public ApiCall<ResponseType, ExceptionType> build() {
198238
return new ApiCall<ResponseType, ExceptionType>(globalConfig,
199239
endpointConfigurationBuilder.build(), requestBuilder,
200240
responseHandlerBuilder.build());

0 commit comments

Comments
 (0)