API 请求分页
API Request Pagination
我正在向 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)
...
您可以先从用户帐户 URL 请求获取回购计数。例如这里是我的:
https://api.github.com/users/erikh2000
那里的响应包含一个 "public_repos" 值。砰!这就是你想要的神奇数字。
如果回购计数超过 100,您接下来需要进行多次提取。我知道您不想这样做,但是嘿...不能责怪网络服务试图节省带宽。好消息是您可以将它们放在 Promise.all() 块中,然后将它们全部提取在一起并立即 return 。所以代码像...
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 想要让您立即为那些有大量回购协议的帐户做的事情。我会对您尝试一次获得的回购数量设置一些 "good citizen" 限制,例如1000。然后通过观察 HTTP 错误响应来查看 api.github.com 是否同意您对好公民的定义。如果需要,您可以使用节流解决方案,但可能像上面那样的 "grab it all at once" 方法可以正常工作。
另一方面,如果您在一个会话中搜索多个帐户,那么也许从一开始就设计节流,只是为了您知道...很好。为此,请查看 queue/worker 模式。
我正在向 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)
...
您可以先从用户帐户 URL 请求获取回购计数。例如这里是我的:
https://api.github.com/users/erikh2000
那里的响应包含一个 "public_repos" 值。砰!这就是你想要的神奇数字。
如果回购计数超过 100,您接下来需要进行多次提取。我知道您不想这样做,但是嘿...不能责怪网络服务试图节省带宽。好消息是您可以将它们放在 Promise.all() 块中,然后将它们全部提取在一起并立即 return 。所以代码像...
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 想要让您立即为那些有大量回购协议的帐户做的事情。我会对您尝试一次获得的回购数量设置一些 "good citizen" 限制,例如1000。然后通过观察 HTTP 错误响应来查看 api.github.com 是否同意您对好公民的定义。如果需要,您可以使用节流解决方案,但可能像上面那样的 "grab it all at once" 方法可以正常工作。
另一方面,如果您在一个会话中搜索多个帐户,那么也许从一开始就设计节流,只是为了您知道...很好。为此,请查看 queue/worker 模式。