1. ホーム
  2. javascript

[解決済み] Stripeのレート制限を乗り越える方法がわからない

2022-02-18 18:35:04

質問内容

StripeとNodeJS(正確にはExpress)を使用して、eコマースサイトのバックエンドを開発しようとしています。

サーバーが起動すると、Stripeから商品を取り込もうとしています。しかし、最初の stripe.products.list を呼び出すと、「APIレートの制限を超えた」というエラーが発生します。これは真実ではありません。 Stripeのドキュメント テストモードでは25/秒に制限されていますが、私は2回目の呼び出しを行う前に10秒待っています。

私が呼び出しに使用している関数を以下に示します。私はこれを単純にループで使い、それぞれの呼び出しの前にsleep()関数を使用しています。

async function fetchFromLastObj(last_obj){

    const data = stripe.products.list({ 
        active: true,
        limit: maxRetrieve,
        starting_after: last_obj,
    })
    .then((resp) => {
        console.log(`Retrieved ${resp.data.length} products.`);
        return resp.data;
    })
    .catch((e) => {  });

    return data;
}

スリープ機能です。

const { promisify } = require('util')
const sleep = promisify(setTimeout)

問題のループ

    var last_obj_seen = null;
    var nb_iters = 0;

    // fetching all products from stripe
    while (true) {
        console.log(`Iteration ${nb_iters+1}...`)

        let fetchedList = [];

        if (last_obj_seen == null) {
            fetchedList = await fetchFirstBatch();
        } else {
            fetchedList = await fetchFromLastObj(last_obj_seen);
        }

        fetchedList = Array.from(fetchedList);
        if (fetchedList.length == 0) { break; };
        last_obj_seen = fetchedList.slice(-1)[0];

        await sleep(10000);
        fetchPrices((fetchedList)) 
        .then((fetchedListWithPrices)=>{
            saveList(fetchedListWithPrices);//not asynchronous
        })
        .catch((err) => { console.error("While fetching products from Stripe..."); console.error(err); });

        nb_iters += 1;
        if(nb_iters > 100){ throw Error("Infinite loop error"); }
        if (nb_iters !== 0){
            console.log("Waiting before request...");
            await sleep(10000);
        }
    }
    console.log("Done.");

解決方法は?

ページネーションロジックを自分で処理するのではなく Stripeの公式ライブラリの自動ページング機能である .

当社のライブラリはオートパジネーションに対応しています。この機能は、手動で結果をページ分割し、その後のリクエストを実行することなく、リソースの大きなリストの取得を簡単に処理することができます。

Node 10+では、例えばこんなことができます。

for await (const product of stripe.products.list()) {
  // Do something with product
}

Stripe Nodeライブラリは、あなたのためにボンネットの下でページネーションを処理します。