如何在响应大小有限时获取更多API记录

问题描述 投票:1回答:3

我对React或JavaScript没有多少经验。我正在创建一个从API获取时间序列数据的简单应用程序。该数据用于绘制折线图(React Apex Chart)。都好。

问题是API响应大小限制为最多2,000条记录,有时我们需要更多数据。

The API documentation says:

响应大小限制为最多2,000条记录。如果必须返回更多记录,则响应头包含带有URI的链接头,以获取下一组记录:

链接:https://apiurl;为rel = “下一步”

My Fetch Code:

我的代码获取api数据,对其进行排序并将其发送到子组件(Chart)。

  FetchAPI(){
    fetch(https://MYURLHERE?from=FROMDATE&to=TODATE)
      .then(response => response.json())
      .then(data => this.setState({ 
        kWhData: data.map((kWh) => kWh._kWh),
        TimeStampData: data.map((time) => time._time),
        loading: false
      }))
      .catch(error => console.log('Fetching failed', error))
  }
Link header: link →<https://MYURLHERE?from=FROMDATE&limit=2000&to=TODATE>; rel="next">

我知道解决方案可能是某种分页但我不完全理解这个概念。我搜索了类似的问题但没有运气。

希望有人能为我提供帮助,提示或代码。

javascript reactjs api fetch
3个回答
2
投票

我不知道您正在使用什么API,但听起来您需要做的就是从头部获取下一组结果的URL,然后向其发出请求。

在返回response.json()之前,您可以使用response.headers.get()访问标题。因此,您可以执行类似let nextPage = response.headers.get('Link')的操作,将完整的Link标头作为字符串。然后,您可以在分号处拆分它,并使用第一部分作为下一个分页请求的URL。


2
投票

如果我正确理解了这个问题,我会在你的FetchApi函数中添加一个变量,这样它就可以查询你的初始API URL或后续页面的URL:

FetchAPI(requestURL){
    // Fetch function here
}

这个想法是,这个函数可以迭代地调用自己,结果的'next'页面的url作为每个调用的参数传递,直到响应指示已经检索了所有数据。

所以你的初始调用是FetchAPI('https://MYURLHERE?from=FROMDATE&to=TODATE')。

如果达到速率限制,您可以再添加一行来再次调用此函数。例如:

FetchAPI(requestURL){
    fetch(requestURL)
        .then(response => {
            if(response.dataLimit == true){ // Or however this is expressed
                // Concat new data with any already retrieved
                this.FetchAPI(nextPageUrl) // Get the URL of the next page and call FetchAPI again with this e.g https://MYURLHERE?from=FROMDATE&limit=2000&to=TODATE
            } else {
                // Otherwise stop and do something else now that you have a complete set of data
            }
        })
}

值得一提的是,这是未经测试的代码,但希望足以让原则得到解决。

此外,如果API具有请求率限制,例如1秒,您可以在函数再次调用之前添加延迟,但显然这会影响检索所有数据的总时间。


0
投票

谢谢你们。我得到了两个答案的混合工作。

我不知道这是一个好方法,还是“正确”的方法。也许你们可以给我一些反馈?

setTimeout仅用于测试,但我认为我需要至少1000?

获取API需要凭证/标头。

FetchAPI(requestURL) {
    fetch(requestURL, {
        credentials: 'include',
            headers: {
                "Content-Type": "application/json",
                "Accept": "application/json",
                "x-xsrf-token": this.myXRSFToken,
                "origin": `${window.location.protocol}//${window.location.host}`
            }
        })
    .then(response => {
        let Responseheader = response.headers.get('Link')
        response.json()
        .then(data => this.setState({
            TestData: this.state.TestData.concat(data)
        }))
        if (Responseheader){
            let nextPageUrl = Responseheader.match(/\bhttps?:\/\/\S+Z/gi)
            setTimeout(() => {
                this.FetchAPI(nextPageUrl)
            }, 2000);
        } else {
            console.log('Done fetching API')
            this.setState({ 
                loading: false
            })
            return
          }  
    })
    .catch(error => console.log('Fetching failed', error))
}
© www.soinside.com 2019 - 2024. All rights reserved.