.Net SDK: inconsistent availablility of underlying List/Search paging mechanism

Folks:

I’m attempting to build an integration application in C# which talks to the Square API. The application will be calling multiple API endpoints to poll changed data, and I was hoping that I could develop a single consistent, reusable pattern to access the list/search API endpoints, which are very similar to each other - but the Square .Net SDK is not allowing me to do that.

For example, the Customers.SearchAsync() method returns a SearchCustomersResponse object that contains one page of data plus the cursor value for the next page, if there is any. This is simple and mirrors the actual API definition and allows me to explicitly code pagination in a manner our application already supports.

However, the GiftCards.Activities.ListAsync() method has similar parameters but returns a Pager<GiftCardActivity> that encapsulates the pagination details. Even though the ListActivitiesRequest object has a Cursor property, there is no apparent way to get the cursor value from the current page to provide to a request for the next page, so that a code pattern consistent with customer search could be used.

The GiftCards.Activities.ListAsync() method does have exactly what I want, it just doesn’t expose it for public use:

    private async Task<ListGiftCardActivitiesResponse> ListInternalAsync(
        ListActivitiesRequest request,
        RequestOptions? options = null,
        CancellationToken cancellationToken = default
    )
    {
        ...
    }

The GiftCards.ListAsync() method has the same problem: the only way to use it is via the provided Pager<GiftCard> wrapper which encapsulates the details of pagination.

This inconsistency, and the way it blocks creating list/search API request code using one reusable pattern, is extremely frustrating.

It’s fine having a client method that returns a Pager that hides all of the details of pagination for large response sets to make it easier to code for the API, but not when that comes at the cost of not being able to manage pagination myself if I wish to.

Please have the SDK provide consistent access methods across all of the endpoints, as far as possible, to allow an application to use either approach (explicit paging, or implicit “automatic” paging behind a Pager) as needed: either expose the ListInternalAsync() method for use somehow, or expose the current page’s “next page” cursor value in the Page<TItem> object..

Neither of the workarounds that I see - using reflection to access the private list method, or using a local fork of the Square SDK library with custom changes - are appealing.

Thank you.

:waving_hand: I’m Square Dev AI, here to help answer your question!
Based on the information you’ve provided, the following documentation will help answer your question:

Additional Documentation

Use a Gift Card (Orders and Payments Integration)
Common Square API Patterns
Retrieve Gift Cards and Track Activity

If this documentation helped you find a solution, please check the box indicating that this reply solves the problem.
Otherwise one of our Developer Advocates will provide additional assistance shortly.

The recommended documentation resources do not help, as the Square .Net SDK hides pagination details for some endpoints.

The Square .NET SDK provides different methods for handling pagination depending on the specific API endpoint. For the Customers.SearchAsync() method, the SDK returns a SearchCustomersResponse object that includes a cursor for the next page of results, allowing you to handle pagination manually.

However, for the GiftCards.Activities.ListAsync() and GiftCards.ListAsync() methods, the SDK returns a Pager<GiftCardActivity> and Pager<GiftCard> object respectively. These objects encapsulate the details of pagination, and the SDK handles the pagination automatically for you.

The inconsistency you’re seeing is due to the different ways these API endpoints are designed to handle pagination. While it might seem inconsistent, it’s designed to provide flexibility and convenience for different use cases.

For endpoints that return a large amount of data, the SDK provides the Pager object to simplify the process of handling pagination. This is useful in scenarios where you want to retrieve all results without having to manually handle the pagination.

On the other hand, for endpoints that typically return a smaller amount of data, the SDK provides a cursor that you can use to manually handle pagination. This gives you more control over the pagination process and can be useful in scenarios where you want to retrieve a specific page of results.

Currently, there isn’t a way to manually handle pagination for methods that return a Pager object. If you need this functionality, you might consider submitting a feature request to the Square Developer team.

This answer was reviewed by @Bryan-Square.

Sure, it’s great to have helpers like that available, but not when they assume they will be the correct solution for all problems and entirely block access to the underlying raw request pagination mechanism.

That’s what this conversation is.