🔁

TypeScriptの `for await...of` でAPIのページングをする

に公開

StripeのNode.js SDKには「Auto-pagination」という機能があります。
自動でページングを行なって for await...of で処理できるようにしてくれます。

実例を挙げると以下のような形となり、スッキリとイミュータブルな処理に書けて気持ち良いです。

一般的なページング
(async () => {
  const customers: Stripe.Customer[] = [];
  let starting_after: string | undefined = undefined;

  do {
    const response = await stripe.customers.list({
      starting_after,
    });

    for (const customer of response.data) {
      customers.push(customer);
    }

    starting_after = response.has_more
      ? response.data[response.data.length - 1].id
      : undefined;
  } while (starting_after);

  console.log(JSON.stringify(customers));
})();
Auto-paginationあり
(async () => {
  const customers: Stripe.Customer[] = [];

  for await (const customer of stripe.customers.list()) {
    customers.push(customer);
  }

  console.log(JSON.stringify(customers));
})();

テンプレート

一般的なREST APIでも同様の使い勝手でページングできるといいと思ったのでテンプレートコードを書きました。

URLやページングにどの要素を使うかなどはAPIに合わせて調整してください。

async function* fetchData() {
  let page: string | undefined = undefined;

  do {
    const response = await fetch(`https://example.com/api?page=${page}`);
    const json = await response.json();

    for (const data of json.data) {
      yield data;
    }

    page = json.naxePage;
  } while (page);
}

(async () => {
  for await (const data of fetchData()) {
    console.log(data);
  }
})();

Discussion