LoginSignup
0
0

More than 1 year has passed since last update.

ExpressでS3からCSVファイルのデータを取得(ついでにSSMパラメータを取得)する方法簡易メモ

Posted at

やりたいこと

idList.csvというCSVファイルをS3に格納
ExpressでS3からidList.csvファイルのデータを取得
idList.csvファイルを格納しているバケット名はSSMで管理

※idList.csvファイルの中身はこんな感じ
スクリーンショット 2023-01-11 23.13.05.png

S3にファイルアップロード

Amazon S3 > Buckets > Create bucket
でバケットを(ap-northeast-1で)作成し、idList.csvファイルをアップロードする

スクリーンショット 2023-01-11 23.11.47.png
バケット名は伏せている

バケット名をSSMパラメータで定義する ※jsのコードにベタ書きでよければ不要

AWS Systems Manager > Parameter Store > Create parameter

BUCKET_NAME_ID_LISTというキーに先程作成したバケット名を登録した
スクリーンショット 2023-01-11 23.10.51.png

jsコード

% npm i @aws-sdk/client-s3 aws-sdk ※typescriptに必要なパッケージは省略(後述のgithubに記述)

index.ts
import express from 'express';
import { GetObjectCommand, S3Client } from '@aws-sdk/client-s3';
import { SdkStream } from '@aws-sdk/types';
import { Readable } from 'stream';
import AWS from 'aws-sdk';

const app = express();
const port = 3000;

const ssm = new AWS.SSM({ region: 'ap-northeast-1' });
const s3Client = new S3Client({ region: 'ap-northeast-1' });

// 取得したCSVのデータストリームをListに変換
const streamToList = (stream: SdkStream<Readable>): Promise<string[]> =>
    new Promise((resolve, reject) => {
        const items: string[] = [];
        const splitter = /[\r\n]+/;
        let leftOver = '';

        const toItems = (data: string[]): string[] => data.filter((line) => line.trim()).map((id) => id);

        stream.on('data', (chunk: Uint8Array) => {
            const data = `${leftOver}${chunk.toString()}`.split(splitter);
            leftOver = data.pop() || '';
            items.push(...toItems(data));
        });
        stream.on('error', reject);
        stream.on('end', () => resolve(items.concat(leftOver ? toItems(leftOver.split(splitter)) : [])));
    });

export async function getIdListFromS3(): Promise<string[]> {
    try {
        // SSMからバケット名取得
        const { Parameter } = await ssm
            .getParameter({
                Name: 'BUCKET_NAME_ID_LIST',
                WithDecryption: true,
            })
            .promise();
        // S3からCSVファイルデータ取得取得
        const { Body } = await s3Client.send(
            new GetObjectCommand({
                Bucket: Parameter?.Value,
                Key: 'idList.csv',
            })
        );
        return await streamToList(Body as SdkStream<Readable>);
    } catch (e) {
        console.error(`List取得でエラー発生:${(e as Error).message}`, e);
        return [];
    }
}

app.get('/', async (req, res) => {
    const ids = await getIdListFromS3();
    res.send(ids);
});
app.listen(port, () => {
    console.log(`Example app listening on port ${port}`);
});

参考

動作確認

スクリーンショット 2023-01-11 23.19.59.png

コード全体、バージョン情報等はこちら

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0