AWSの、Describe*系とかList*系のAPIを実行する時、リソースが多すぎると、一回のリクエストで全部を取得できない。
なので、「前回のリクエスト続きのデータを取る」リクエストを何回も行う(ページング)。
AWS SDK for JavaScriptでページングする方法は、下記のドキュメントに書かれてる。
https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/the-response-object.html#response-paged-data
このコードを逐一書くのは若干面倒なので、一般化してみる。
const AWS = require('aws-sdk');
let paging = (awsRequest, callback) => {
let handlePageError = (error, response) => {
callback(response.error, response.data);
};
let handlePage = (response) => {
callback(null, response.data);
if (response.hasNextPage()) {
response.nextPage().on('error', handlePageError).on('success', handlePage).send();
}
};
awsRequest
.on('error', handlePageError)
.on('success', handlePage)
.send();
};
let s3 = new AWS.S3();
let bucket = 'バケット名';
// let ep = new AWS.Endpoint('http://500.returnco.de'); // for error test
// let s3 = new AWS.S3({endpoint: ep}); // for error test
paging(s3.listObjectsV2({Bucket: bucket, MaxKeys: 10}), (err, data)=>{
if(err) console.log(err, err.stack);
console.log('---- ---- ---- ----');
for(let i=0; i<data.Contents.length; i++) console.log(data.Contents[i].Key);
});
核心部分は、paging関数。
AWS.Requestとコールバックを渡すと、レスポンス受け取るたびにコールバックが動く。
paging関数の動作は、listObjectsV2メソッドで確認した。
MaxKeysで、1リクエストあたり10のオブジェクトをリストするようにしているので、上記コードを動かすと、オブジェクトが10ずつ表示されていく。
雑記
エラー処理はいちおう書いてみたけど、ちゃんと動作確認はしてない。。。
Promiseを使いつつpagingする良い方法がないかなーというのもちょっと考えてみたけど、良い方法思いつかなかった。。。