NodejsでS3にファイルをアップロード・ダウンロード


### 概要

こちら記事では、NodeJSでローカルでS3アップロードとダウンロードの基本的な方法を書かせていただきます。
<details><summary>内容として５つあります</summary>
    
    1.環境
    
    2.前提
    
    3.初期設定
    
    4.アップロード
    
    5.ダウンロード
    
    6.最後
    
    7.参考

</details>




### 1.環境

- Nodejs v21.6.0
- MacOS

### 2.前提

- デモ用のS3 バッケットが作成済み
- ローカルに認証情報ファイル設定ずみ　（まだ設定しない場合は[こちら](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-files.html)をご参考してください）
- プロフィルにせめてS3アクセス権を付与
- デモ用画像を準備



### 3.初期設定

作業のフォルダを作成

```bash
desktop/mkdir demo-s3-upload-download
cd demo-s3-upload-download
npm init
// いくつかの質問が出てくるが、そのままにしても大丈夫
```

**必要なライブラリをダウンロード**

- @aws-sdk/client-s3 :  S3に操作のツールが整いておく

- dotenv：  環境変数を取るため

```bash
npm i @aws-sdk/client-s3  dotenv
```

__AWSの認証情報を取って環境ファイルに保存__

.env を作成

```bash
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_REGION=
```

重要な情報なので、Gitにアップロードしたら.gitignore に.env を登録するのが必須

```bash
/node_modules/
.env
```

__AWS認証情報を取って、.env に該当する情報を入れる__

メモ:[trungadmin] こちらはAWSブロフィルである。貴方のローカルには色んなブロフォルがあるかもしれません。それで、プロファイルを注意してください。

```bash
cat ~/.aws/credentials
結果は下のように
[default]
aws_access_key_id = 
aws_secret_access_key = 
[trungadmin]
aws_access_key_id = 
aws_secret_access_key = 
```

### 4.アップロード


```demo-download-upload-file-s3.js``` という作業ファイルを作成　


```bash
作業フォルダのツリー
｜
｜ーdemo-download-upload-file-s3.js
｜ーfor-demo.png
｜。。。。
```

```js
// 作業ファイル
const {
  S3Client,
  GetObjectCommand,
  PutObjectCommand,
} = require("@aws-sdk/client-s3"); // AWSのS3用ライブラリ
const fs = require("fs"); // ファイルを読み込むのため
require("dotenv").config();

// S3 バッケット名
const DEMO_BUCKET = "demo-pre-resize-image";

// 認証の設定
//こちらの仕方はベストプラクティスではない
const S3 = new S3Client({
  region: process.env.AWS_REGION,
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  },
});

// ローカルのファイルを読み込んでS3にアップロードします
// *srcPath: ローカルに保存しているファイルのパス
// *fileName: S3でファイル名を決める
// *バッケット名

const uploadLocalFileToS3 = async (srcPath, fileName, bucketName) => {
  //ストリームを開ける
  const readStream = fs.createReadStream(srcPath);
  try {
    const command = new PutObjectCommand({
      Bucket: bucketName,
      Key: fileName,
      Body: readStream,
    });
    await S3.send(command);
  } catch (error) {
    console.log(error);
  } finally {
    //ストリームを閉める
    readStream.close();
  }
};

uploadLocalFileToS3('./for-demo.png','test1.png',DEMO_BUCKET)
```

テストを行う

```bash
node demo-download-upload-file-s3.js
```

S3で結果をチェック
![Screen Shot 2024-02-08 at 14.04.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703979/f2485f15-49c3-1005-8ccb-dd5e536c14e8.png)





### 5.ダウンロード

引き続き書く

```bash

// S3に保存してるファイルをダウンロード
// *desPath: ローカルに保存する予定のファイルのパス
// *fileName: S3でファイル名
// *バッケット名

const downloadFileFromS3ToLocal = async (desPath, fileName, bucketName) => {
  try {
    const command = new GetObjectCommand({
      Bucket: bucketName,
      Key: fileName,
    });
    const response = await S3.send(command);
    response.Body.pipe(fs.createWriteStream(desPath))
      .on("error", (error) => {
        throw error;
      })
      .on("close", () => {
        console.log("completed");
      });
  } catch (error) {
    console.log("error", error);
  }
};

downloadFileFromS3ToLocal("./downloaded/image_s3.png", "test1.png", DEMO_BUCKET);
```

テストを行う

```bash
node demo-download-upload-file-s3.js
```

ローカルはこんな感じ

![Screen Shot 2024-02-08 at 14.06.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703979/02619fd5-61a1-3b88-1e0b-6fbd39cd7aea.png)

### 6.最後

皆さんは大体S3へファイルのアップロード・ダウンロード処理を把握できると思います。こちら処理は小さい段階の経過です。経過は例えばファイルにウィルスがあるかチェックするやファイルを圧縮するです

次は同じテーマを書くつもりです。

[全てソースコードはこちら](https://github.com/17021084/s3-aws-resized-image-js/tree/for-demo-post
)

最後まで読んで頂いて有り難うございます。:bow:
役に立つを感じしたらハートやコメントやを残ってください:bow:

### 7.参考



https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/s3/command/PutObjectCommand/

https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/s3/command/GetObjectCommand/#:~:text=Body-,StreamingBlobPayloadOutputTypes,-Throws

https://www.tutorialspoint.com/nodejs/nodejs_streams.htm