はじめに
実務にて、@aws-sdk/client-s3ライブラリを用いて、
S3オブジェクトの取得・保存機能
の実装を行いましたので、備忘録として参考ロジックの記載になります。
目次
🪄 使用パッケージ
s3/packages.json
"dependencies": {
"@aws-sdk/client-s3": "^3.738.0",
"inversify": "^6.0.2"
},
🪄 メインロジック
s3/repository/index.ts
import { GetObjectCommand, PutObjectCommand, S3Client } from '@aws-sdk/client-s3';
import { injectable } from 'inversify';
import type { Readable } from 'node:stream';
import type { IS3Repository } from './interface';
@injectable()
export class S3Repository implements IS3Repository {
private readonly s3Client: S3Client;
constructor() {
const configuration =
process.env.ENV === 'local'
? {
region: process.env.AWS_REGION || 'ap-northeast-1',
endpoint: process.env.LOCAL_STACK_ENDPOINT || 'http://localhost:3000',
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID || 'test',
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || 'test',
},
forcePathStyle: true,
}
: {};
this.s3Client = new S3Client(configuration);
}
/**
* S3オブジェクトを取得する
*
* @param bucket - バケット名
* @param key - キー
* @returns オブジェクトの内容
*/
public async getObject(bucket: string, key: string): Promise<Buffer> {
try {
const command = new GetObjectCommand({ Bucket: bucket, Key: key });
const response = await this.s3Client.send(command);
if (!response.Body) {
throw new Error('S3オブジェクトの取得に失敗しました');
}
const stream = response.Body as Readable;
const chunks: Uint8Array[] = [];
for await (const chunk of stream) {
chunks.push(chunk);
}
return Buffer.concat(chunks);
} catch (error) {
if (error instanceof Error) {
throw new Error('s3 getObject error:', {
message: error.message,
stack: error.stack,
params: { bucket, key },
});
}
throw error;
}
}
/*
* S3オブジェクトを保存する
*
* @param bucket - バケット名
* @param key - キー
* @param body - 保存する内容
*/
public async putObject(bucket: string, key: string, body: Buffer<ArrayBufferLike>): Promise<void> {
try {
const command = new PutObjectCommand({ Bucket: bucket, Key: key, Body: body });
await this.s3Client.send(command);
} catch (error) {
if (error instanceof Error) {
throw new Error('w3 putObject error:', {
message: error.message,
stack: error.stack,
params: { bucket, key },
});
}
throw error;
}
}
}
🪄 インターフェース
s3/repository/interface.ts
export interface IS3Repository {
/**
* S3オブジェクトを取得する
*
* @param bucket - バケット名
* @param key - キー
* @returns オブジェクトの内容
*/
getObject(bucket: string, key: string): Promise<Buffer>;
/**
* S3オブジェクトを保存する
*
* @param bucket - バケット名
* @param key - キー
* @param body - 保存する内容
*/
putObject(bucket: string, key: string, body: Buffer<ArrayBufferLike>): Promise<void>;
}
🪄 まとめ
処理概要
- S3Clientインスタンス化
- S3オブジェクト取得
- S3オブジェクト保存
改良点
-
throw new Error
箇所は、ロガーライブラリを用いてカスタム可能なエラークラスを別ファイルで作成・参照する形にすると良い! - 上記はさらに、@sentry/nodeを用いて、Sentry通知可能にするとより実務的なサービス構成になる