bchavez / Coinbase

:moneybag: A .NET/C# implementation of the Coinbase API.
https://developers.coinbase.com/api/v2
MIT License
170 stars 93 forks source link

Question: How to work with PagedResponses? #54

Closed lucaswalter closed 5 years ago

lucaswalter commented 5 years ago

My apologies if has been documented somewhere but I wasn't able to find an example or best practices when working with the PagedResponse object. Right now, I am trying to retrieve all Buys from an account that has more buys than can be returned in a single page.

Using this library, is the best approach to:

  1. Initially list the buys
  2. Get the NextUri from that response
  3. Make all subsequent requests using client.HttpClient

Or is it possible to do this in a more graceful way that has already been implemented?

var buyResponse = await client.Buys.ListBuysAsync(account.Id);
var nextUri = buyResponse.Pagination.NextUri;

while (!string.IsNullOrEmpty(nextUri))
{
    var nextPage = await client.HttpClient.GetAsync(nextUri);

    // Deserialize

    // Check For Next URL
}

Thanks!

bchavez commented 5 years ago

Hi Lucas,

Pagination is a bit more of a manual process. You'll have to pick off the response.Pagination.NextUrl property and use Flurl to complete the request for the next page.

The CoinbaseClient is just a light weight wrapper around Flurl, so it should be somewhat straight forward.

Perhaps, I should add some helper methods to the client.

Either way, here's how you'd do it:

[Test]
public async Task test_paged_response()
{
   var accounts = await client.Accounts.ListAccountsAsync();
   var btcWallet = accounts.Data.First(a => a.Name.StartsWith("BTC Wallet"));

   var firstAddressesPage = await client.Addresses.ListAddressesAsync(btcWallet.Id);
   firstAddressesPage.Dump();

   var nextAddressesPage = client.NextPageAsync(firstAddressesPage);
   nextAddressesPage.Dump();
}

public static class ExtensionsForClient
{
   public static Task<PagedResponse<T>> NextPageAsync<T>(this CoinbaseClient client, PagedResponse<T> currentPage, CancellationToken cancellationToken = default)
   {
      if( currentPage?.Pagination?.NextUri is null ) throw new NullReferenceException("No next page.");

      var nextUrl = currentPage.Pagination.NextUri.Remove(0, 4);

      return (CoinbaseClient.Endpoint + nextUrl)
         .WithClient(client)
         .GetJsonAsync<PagedResponse<T>>(cancellationToken);
   }
}

Let me know if that works for you.

Thanks, Brian

lucaswalter commented 5 years ago

Thank you very much Brian! Doing some testing with that extension right now.