AWS S3のバケットからテキストファイルを取り出そうとしてハマった件

AWSのS3の getObject APIで取り出したファイルの内容は、
Bufferクラスのインスタンスとして response.Bodyに収められているので、テキストファイルの中身を文字列として得たいなら、以下のようにすれば一発です。
let text = response.Body.toString("utf-8");
API叩くところも含めると以下のようになる。
"use strict";
const AWS = require("aws-sdk");
const S3 = new AWS.S3();
function S3_getObject(bucket, key) {
    return new Promise( (resolve, reject) => {
        S3.getObject(
            {Bucket: bucket, Key: key },
            (err, response) => {
                if(err) { reject(err); }
                else { resolve(response); }
            }
        );
    });
}
(async ()=> {
    let response = await S3_getObject("mybucket", "foo.json");
    let text = response.Body.toString("utf-8");
    console.log(text);
})();
しかし初めてのS3だったので、変換前に response.BodyをJSON.stringifyで確認すると、{"type":"Buffer", "data":[ ... ]} などと表示され、「なるほど data に生の配列として入ってるのね」と思ってしまい、Buffer.from(response.Body.data) とやってエラーになった。「コンストラクタの第一引数は文字列じゃないと・・・」みたいなエラー。「わけわからん」と response.Body.data を確認すると、なぜかこれが undefinedになっている(上ではJson的にキーがあると表示されているのに)。
いまだに、どうしてこうなるのか理解できないままでいる。
まあ、本質的には「APIの仕様をきちんと把握してから挑みましょう」ということなのだが。
以下、確認コードも含めて再掲(前半部分は端折ってある):
(async ()=> {
    let response = await S3_getObject("mybucket", "foo.json");
    console.log(JSON.stringify(response.Body));
        // ↑ {"type":"Buffer", "data":[ ... ]}
        // などと表示される
    console.log(JSON.stringify(response.Body.type));
        // ↑ undefined なんで?
    console.log(JSON.stringify(response.Body.data));
        // ↑ undefined なんで?
    let textFail = Buffer.from(response.Body.data);
        // ↑ Error undefindから構築できない。 
    let text = response.Body.toString("utf-8");
        // ↑ これが正解
    console.log(JSON.strngify(JSON.parse(text)));
})();

0 件のコメント: