API请求分页

时间:2017-05-21 23:13:51

标签: api reactjs github axios

我正在向Github发送一个简单的API请求以获取所有存储库。问题是Github有一个限制,它可以发送的最大值是每个请求100。有些用户拥有超过100个存储库,我不知道如何访问它或如何进行分页。

我正在向Axios发出GET请求:

https://api.github.com/users/<AccountName>/repos?per_page=100

我也可以像这样放置页码

https://api.github.com/users/<AccountName>/repos?page=3&per_page=100

但是如何在应用程序中完成此工作而不会发出10个API请求?我甚至不知道应该提出多少请求,因为我不知道返回的号码是多少,有人有100或1000个回购?例如,我希望将所有内容都返回并保存在数组中。

编辑: 示例:我传递的是accountName

var config = {
  headers: {'Authorization': `token ${ACCESS_TOKEN}`}
}

const REQUEST: string = 'https://api.github.com/users/'

const apiCall = {
  getData: async function (accountName) {
    const encodedAccountName = encodeURIComponent(accountName)
    const requestUrl = `${REQUEST}${encodedAccountName}`

    const user = await axios.get(requestUrl, config)
// This return user and inside of user there is a link for fetching repos
    const repo = await axios.get(`${user.data.repos_url}?per_page=100`, config)

    ...

1 个答案:

答案 0 :(得分:2)

您可以先通过用户帐户网址请求获取回购计数。例如,这是我的:

https://api.github.com/users/erikh2000

那里的回复包括&#34; public_repos&#34;值。巴姆!这是你想要的神奇数字。

如果回购计数超过100,您接下来需要进行多次抓取。我知道您不想这样做,但是嘿......不能指责Web服务试图节省带宽。好消息是你可以将它们放在Promise.all()块中并将它们全部一起取出并立即返回。所以代码就像......

const fetchAllTheRepos = (userName, repoCount) => {
  const MAX_PER_PAGE = 100;
  const baseUrl = 'https://api.github.com/users/' + userName +
    '/repos?per_page=' + MAX_PER_PAGE;

  //Start fetching every page of repos.
  const fetchPromises = [], pageCount = Math.ceil(repoCount / 
    MAX_PER_PAGE);
  for (let pageI = 1; pageI <= pageCount; ++pageI) {
    const fetchPagePromise = fetch(baseUrl + '&page=' + pageI);
    fetchPromises.push(fetchPagePromise);
  }

  //This promise resolves after all the fetching is done.
  return Promise.all(fetchPromises)
  .then((responses) => {
     //Parse all the responses to JSON.
     return Promise.all( responses.map((response) => response.json()) );
  }).then((results) => {
    //Copy the results into one big array that has all the friggin repos.
    let repos = [];
    results.forEach((result) => {
      repos = repos.concat(result);
    });
    return repos;
  });
};

//I left out the code to get the repo count, but that's pretty easy.
fetchAllTheRepos('erikh2000', 7).then((repos) => {
    console.log(repos.length);
});

同时获取所有页面可能最终会超过Github想要让那些有大量回购的帐户立即执行。我会把一些&#34;好公民&#34;限制您试图立即获得的回购数量,例如1000.然后通过观察HTTP错误响应来查看api.github.com是否同意您对好公民的定义。如果需要,您可以进入限制解决方案,但可能会立即抓住所有解决方案&#34;上面的方法很好。

另一方面,如果你在一个会话中通过多个帐户进行搜索,那么可能从一开始就设计限制,直到你知道......很好。为此,请查看队列/工作者模式。