Shopify GraphQL Admin API速率限制成本和睡眠时间

时间:2018-11-25 16:38:10

标签: php laravel graphql shopify shopify-app

我正在尝试在PHP(Laravel)中使用Shopify GraphQL API进行管理。
与REST api相比,GraphQL api中的速率限制和节流的作用不同,REST api是根据查询的 cost 计算的。

Cost of Shopify GraphQL query



需要牢记的几点:

  • 一个API调用(查询)的最大可用费用为1000。
  • 如果您消耗了1000点中的某些点,每秒将恢复50点。
  • 如果您的存储桶中的成本点较少,而您查询的成本点高于该成本点,则会降低成本。

我要传递给api的查询的估计费用为 502 ,由 requestedQueryCost 表示。而 actualQueryCost 代表api针对特定商店返回的实际响应

在上面的快照中,对于具有大量订单的商店,其最坏的情况 requestedQueryCost 等于 acutalQueryCost

现在,执行此查询时,我消耗了502点,还剩498点,经过1秒,添加了50点= 548 ,并且我可以进行第二次api调用以获取第二页数据。在第二次api调用后,我剩下的点数减少了,因此我必须将 sleep 放置1或2秒钟才能获得要进行api调用的点数。

在快照所示的情况下,我必须放置 10秒睡眠等待时间才能恢复 500点以便进行下一个api调用。

问题:如何最好地决定不同商店的睡眠(等待)时间?我们不希望所有商店都等待10秒,即使它们的查询成本较低。

注意:有关代码参考,请参见下面的答案。

2 个答案:

答案 0 :(得分:0)

您会清楚地收到每家商店的费用查询电话。如果一家商店为零,那么您可能还有1000个在另一家商店等您。您应该确保您的调用机制明确无误!每个商店只能睡一个线程。您应该能够将请求分配给线程,这样,即使它休眠了,您仍然可以与其他线程一起操作。如果PHP用分配给所有请求的一个线程来操作,那我会很不高兴。那将是1982年的计算结果!

答案 1 :(得分:0)

下面是我的解决方案草稿,仍在寻找有关如何有效处理该问题的专家意见,以便根据数据量,每个商店都必须等待应得的时间。请指教。

public function getRequiredOrders()
{
    $firstRequestTimeStamp = now();
    $ordersGraph = $this->shop->api()->graph($this->firstQuery())->body->orders;
    $this->transform($ordersGraph); //transforming to required format

    $previousRequestTimeStamp = $firstRequestTimeStamp;

    while($ordersGraph->pageInfo->hasNextPage) {

        $nextRequestTimeStamp = now();
        $timeElapsed = $nextRequestTimeStamp->diffInSeconds($previousRequestTimeStamp);
        $restoredPoints = $timeElapsed * 50; //50 points are restored every 1 second
        $pointsLeft = $this->shop->api()->getApiCalls('graph', 'left');
        $totalPointsLeft = $pointsLeft + $restoredPoints;

        if($totalPointsLeft >=502){ //one must know the maximum cost of their query
            $lastEdgeCursor = end($ordersGraph->edges)->cursor;
            $nextQuery = $this->nextQuery($lastEdgeCursor);
            $previousRequestTimeStamp = $nextRequestTimeStamp;
            $ordersGraph = $this->shop->api()->graph($nextQuery)->body->orders;
            $this->transform($ordersGraph);
        }else{
            sleep(1);
            continue;
        }

    }
    return $this->allOrders;
}