如何在Flutter/Dart中通过Shopify REST API获取全部商品
解决Shopify REST API获取全部商品的分页问题
以下是完整的实现代码,附带关键逻辑的解析:
List<ProductModel> productList = []; bool isLoading = true; void fetchAllProducts() async { // 初始化请求URL,带上最大限制数250 String? nextUrl = "https://example.myshopify.com/admin/api/2022-01/products.json?limit=250"; // 循环请求直到没有下一页 while (nextUrl != null) { Uri url = Uri.parse(nextUrl); final response = await http.get(url); // 请求失败时终止循环并更新状态 if (response.statusCode != 200) { isLoading = false; notifyListeners(); return; } // 解析当前页商品并追加到总列表 final responseBody = jsonDecode(response.body); List<dynamic> products = responseBody["products"] as List<dynamic>; for(var product in products){ ProductModel productModel = ProductModel.fromMap(product); productList.add(productModel); } // 从响应头中提取下一页的请求地址 nextUrl = _extractNextPageUrl(response.headers['link']); // 更新加载状态:还有下一页则保持加载中 isLoading = nextUrl != null; notifyListeners(); } } // 从Link响应头中解析下一页URL的工具方法 String? _extractNextPageUrl(String? linkHeader) { if (linkHeader == null) return null; // Shopify Link头格式示例:<https://xxx/products.json?limit=250&page_info=xxx>; rel="next", <xxx>; rel="previous" final linkEntries = linkHeader.split(','); for (var entry in linkEntries) { final parts = entry.split(';'); if (parts.length >= 2 && parts[1].trim() == 'rel="next"') { // 去掉URL前后的<>符号 return parts[0].trim().replaceAll('<', '').replaceAll('>', ''); } } return null; }
核心改动说明
- 循环请求所有分页:通过
while循环持续请求下一页,直到响应头中没有next链接为止 - 追加而非替换列表:不再用
productList = tempList覆盖原有数据,改为直接向总列表追加新页商品 - Link头解析:专门编写工具方法提取下一页的完整请求地址,适配Shopify的分页格式
- 加载状态优化:根据是否还有下一页动态更新
isLoading,让UI能正确反馈加载状态
关键细节提醒
- 原代码中的URL缺少
https://前缀,已修正,否则会导致请求失败 - 可根据需求扩展错误处理逻辑(比如重试、日志记录)
- 注意Shopify API的请求速率限制,大量请求时可适当添加延迟避免触发限制
内容的提问来源于stack exchange,提问作者shakti goyal
相关产品推荐
相关产品推荐

