Lambda(node.js)からS3のオブジェクトをGetObjectCommandで取得する – AWS SDK for JavaScript v3

Lambda(node.js)からS3のオブジェクトをGetObjectCommandで取得する – AWS SDK for JavaScript v3

aws sdk for javascript v3のAPIリファレンスを見ていると、クライアントはS3とS3Clientの2つがあるようです。

ここではS3Clientを使用します。s3のオブジェクト取得するので、GetObjectCommandもimportします。

import {S3Client, GetObjectCommand} from '@aws-sdk/client-s3'

export async function handler(event, context) {
  const input = {
    Bucket: '<バケット名>',
    Key: 'tmp/hoge.json' // オブジェクトキー
  }
  const client = new S3Client({
    region: 'ap-northeast-1'
  })
  const command = new GetObjectCommand(input)
  const data = await client.send(command)
  const bodyContents = await streamToString(data.Body)
  console.log(bodyContents) // 文字列で返ってくるのでJSON.parse()で囲んでJSONオブジェクトにする
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    }
    return response;
}

async function streamToString(stream) {
  return new Promise((resolve, reject) => {
      const chunks = [];
      stream.on('data', (chunk) => chunks.push(chunk));
      stream.on('error', reject);
      stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
  });
}

data.BodyにはReadableStreamが返ってくるので、stringに変換する必要があります。

変換する関数はstreamToStringで、AWSの以下ドキュメントのソースを丸々コピーしています。

AWS SDK を使用して Amazon S3 バケットとオブジェクトの使用を開始する - Amazon Simple Storage Service
AWS SDK を使用して Amazon S3 バケットとオブジェクトの使用を開始する

画像(バイナリ)を取得する

画像ファイル(png,jpgなど)をS3から取得するにはstreamからバッファに変換します。

ここではGetObjectCommandで取得した画像ファイルを再度S3にアップロードするサンプルです。

import {
  S3Client,
  GetObjectCommand,
  PutObjectCommand
} from '@aws-sdk/client-s3'

export async function handler(event, context) {
  const s3client = new S3Client({
    region: 'ap-northeast-1'
  })
  const command = new GetObjectCommand({
    Bucket: '<バケット名>',
    Key: 'tmp/s3.png' 
  })
  const data = await s3client.send(command)
  const bodyContents = await streamToBuffer(data.Body)

  const putcommand = new PutObjectCommand({
    Bucket: '<バケット名>',
    Key: 'tmp/s3_new.png',
    Body: bodyContents
  })
  await s3client.send(putcommand)
  const response = {
    statusCode: 200,
    body: JSON.stringify('Hello from Lambda!'),
  }
  return response;
}

async function streamToBuffer(stream) {
  return new Promise((resolve, reject) => {
    const chunks = []
    stream.on('data', chunk => chunks.push(chunk))
    stream.on('error', reject)
    stream.on('end', () => resolve(Buffer.concat(chunks)))
  })
}

ちなみにstreamからTypedArrayに変換しても画像ファイルの保存は可能です。

streamToBufferメソッドをstreamToTypedArrayメソッドに変更して、★部分を変更します。

async function streamToTypedArray(stream) {
  return new Promise((resolve, reject) => {
    const chunks = []
    stream.on('data', chunk => chunks.push(chunk))
    stream.on('error', reject)
    stream.on('end', () => resolve(Uint8Array.from(Buffer.concat(chunks)))) // ★
  })
}

参考サイト

GetObjectCommand | @aws-sdk/client-s3
Documentation for @aws-sdk/client-s3
TypedArray - JavaScript | MDN
TypedArray オブジェクトは、背後にあるバイナリーデータバッファーの、配列風のビューを表します。 TypedArray という名称のグローバルプロパティがあるわけではなく、また直接 TypedArray コンストラクターが見えるわけ...

コメント

タイトルとURLをコピーしました