在整个会话中共享第三方API速率限制

时间:2019-04-02 19:43:37

标签: node.js api express shopify rate-limiting

我正在开发一个简单的应用程序,该应用程序使用第三方API(Shopify REST API),并且通过detailed in their documentation的漏斗算法对Shopify API进行了限制,以允许随时间推移无限请求。

我正在使用Shopify-api-node模块进行API调用,它开箱即用地支持autoLimit选项,该选项会自动限制请求的发送速度,因此您无需考虑API调用限制。

这适用于大多数Node.js脚本,但是在Express应用程序的上下文中遇到麻烦,因为autoLimit选项仅可靠,因此您需要通过会话跨不同的路由共享API实例。一个单一的Shopify实例。

这是我的代码(请注意,我正在为每个路由创建一个新的Shopify实例):

var express = require("express");
var session = require("express-session");
var Shopify = require("shopify-api-node");

var app = express();
var port = 3000;

app.use(session({
  secret: "secret",
  resave: false,
  saveUninitialized: true
}));

app.get("/", (req, res) => {
  var shopName = req.session.shopName = req.session.shopName || req.query.shopName;
  var apiKey = req.session.apiKey = req.session.apiKey || req.query.apiKey;
  var password = req.session.password = req.session.password || req.query.password;

  var shopify = new Shopify({ shopName, apiKey, password, autoLimit: true });

  shopify.on("callLimits", (limits) => console.log(limits));

  var requests = Array.from({ length: 100 }, () => {
    return shopify.shop.get()
  });

  Promise.all(requests)
    .then((requestsRes) => {
      return res.send(JSON.stringify(requestsRes));
    })
    .catch((err) => {
      return res.status(500).send(err);
    });
});

app.get("/other-route", (req, res) => {
  var shopName = req.session.shopName = req.session.shopName || req.query.shopName;
  var apiKey = req.session.apiKey = req.session.apiKey || req.query.apiKey;
  var password = req.session.password = req.session.password || req.query.password;

  var shopify = new Shopify({ shopName, apiKey, password, autoLimit: true });

  shopify.on("callLimits", (limits) => console.log(limits));

  var requests = Array.from({ length: 100 }, () => {
    return shopify.product.list()
  });

  Promise.all(requests)
    .then((requestsRes) => {
      return res.send(JSON.stringify(requestsRes));
    })
    .catch((err) => {
      return res.status(500).send(err);
    });
});

app.listen(port, () => {
  console.log(`Example app listening on port ${port}!`)
});

这是我的package.json

{
  "name": "third-party-api-limit-issue",
  "scripts": {
    "start": "node index.js"
  },
  "dependencies": {
    "express": "^4.16.4",
    "express-session": "^1.15.6",
    "shopify-api-node": "^2.18.1"
  }
}

运行此脚本时,请转到以下URL:

http://localhost:3000?shopName=liquify-app.myshopify.com&apiKey=9d1fae34bf670cc71230fee001486e82&password=dc6f650d5921eb40e7ab1e612e9dae7e

这将向Shopify API发出100个请求,将API凭据存储在会话中并显示商店JSON数据。

如果您同时在两个选项卡中打开相同的URL,或同时打开http://localhost:3000/other-route,则此操作将中断。发生这种情况是因为我不知道如何在我的路线之间共享相同的Shopify API实例。

我需要能够跨路由对API进行尽可能多的调用,而不会遇到“请求过多”错误。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

我认为您的阻抗不匹配。 Shopify有一个限制。它会告诉您确切的位置。所以你提出一个要求。您返回的响应头告诉您可以发出多少个请求。那就是您使用的电话号码。

您说的方法是,我的代码将限制自己,以便不给那边的怪物挠痒痒,因为它不是真正构建请求-响应周期的方式,所以会炸掉。

也许在发布另一个请求之前尝试查看您得到的响应。如果您已达到极限,请在等待铲斗再充电一点时暂停。标准的东西。效果很好。