You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过基础认证发起并发HTTP请求以加速Shopify订单导入

优化Shopify历史订单导入:并发HTTP请求方案

嘿,针对你用httr串行请求Shopify订单速度慢的问题,我给你整理了两个带基础认证的并发请求方案,能大幅提升导入效率,同时适配Shopify的API限制:

首先先搞定Shopify的基础认证——Shopify Admin API的基础认证需要把你的API密钥和密码拼成{api_key}:{password}的格式,再做Base64编码,放到请求头里。代码示例如下:

# 替换成你自己的Shopify信息
api_key <- "你的Shopify API密钥"
api_password <- "你的Shopify API密码"
shop_domain <- "abc-store.myshopify.com"

# 生成基础认证头
auth_header <- httr::add_headers(
  Authorization = paste0("Basic ", openssl::base64_encode(paste0(api_key, ":", api_password))),
  Accept = "application/json"
)

方案1:用furrr + httr实现并行请求

如果你习惯用httr,那用furrr(purrr的并行版)过渡最顺畅,它能把原来的串行循环改成并行执行:

步骤拆解:

  1. 先获取总订单数算出总页数:先请求第一页,从响应里拿到total_count,再计算需要请求多少页(每页250条)。
  2. 配置并行环境:控制并发数,别超过Shopify的速率限制(默认每分钟40请求,所以设5个并发比较安全)。
  3. 并行请求所有页面,最后合并数据。
library(httr)
library(furrr)
library(jsonlite)
library(dplyr)

# 1. 先获取总页数
first_page_url <- paste0("https://", shop_domain, "/admin/orders.json?limit=250")
first_response <- GET(first_page_url, auth_header)
first_data <- fromJSON(content(first_response, "text"))
total_orders <- first_data$total_count
total_pages <- ceiling(total_orders / 250)

# 2. 设置并行会话,workers是并发数,别调太高
plan(multisession, workers = 5)

# 3. 定义单个页面的请求函数,包含错误处理
fetch_single_page <- function(page_num) {
  request_url <- paste0("https://", shop_domain, "/admin/orders.json?limit=250&page=", page_num)
  response <- GET(request_url, auth_header)
  
  # 处理请求失败的情况
  if (httr::http_error(response)) {
    warning(paste("页面", page_num, "请求失败,状态码:", httr::http_status(response)$status_code))
    return(NULL)
  }
  
  # 提取订单数据
  fromJSON(content(response, "text"))$orders
}

# 并行执行所有页面请求
fetched_pages <- future_map(1:total_pages, fetch_single_page)

# 合并所有订单到一个数据框
all_orders <- bind_rows(fetched_pages)

方案2:用httr2异步请求(更现代的选择)

httr2是httr的升级版,原生支持异步请求,代码更简洁,错误处理也更灵活:

library(httr2)
library(jsonlite)
library(dplyr)

# 先创建基础请求模板,包含认证和默认参数
base_req <- request(paste0("https://", shop_domain, "/admin/orders.json")) %>%
  req_headers(
    Authorization = paste0("Basic ", openssl::base64_encode(paste0(api_key, ":", api_password))),
    Accept = "application/json"
  ) %>%
  req_url_query(limit = 250)

# 1. 获取总页数
first_resp <- base_req %>% req_perform()
first_data <- fromJSON(resp_body_string(first_resp))
total_pages <- ceiling(first_data$total_count / 250)

# 2. 生成所有页面的请求列表
page_requests <- purrr::map(1:total_pages, function(page) {
  base_req %>% req_url_query(page = page)
})

# 3. 异步执行请求,控制并发数
responses <- req_perform_parallel(page_requests, workers = 5)

# 4. 处理响应,合并数据
all_orders <- purrr::map_dfr(responses, function(resp) {
  if (resp_is_error(resp)) {
    warning(paste("请求失败,状态码:", resp_status(resp)))
    return(tibble())
  }
  fromJSON(resp_body_string(resp))$orders
})

关键注意点:

  • 速率限制:Shopify默认每分钟40个请求(Plus商店是80),所以并发数别设太高,5-8之间比较稳妥。如果遇到429限流错误,可以给请求加重试逻辑,比如用httr::RETRY或者httr2::req_retry。
  • 错误处理:一定要加错误检查,避免某个页面请求失败导致整个导入流程崩溃。
  • 分页方案:Shopify还支持since_id分页(比基于page的分页更可靠,尤其是导入过程中新增订单的情况),如果你的场景允许,可以考虑改用这种方式,避免重复或遗漏订单。

内容的提问来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:29:53