「Node.jsの使用開始」チュートリアルで S3 の体験

# 背景
業務でAWS に関わることになったので、必要そうな技術を試行中

そもそも、Node.js から理解していなかったので、まずはそれを理解しつつ、以下をやってみることに

https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v3/developer-guide/getting-started-nodejs.html

# 色々やってなんとなく把握したこと
- NVM: Npm の Version 管理。Node.js 使うなら入れたほうがよさげ
    - [windows 版はここで](https://github.com/coreybutler/nvm-windows)
- npm: Node.js の Package 管理。
- [package.json](https://docs.npmjs.com/cli/v6/configuring-npm/package-json): これを元に bulid してくれる感じ？
    - dependencies: 本番用
    - devDependencies: 開発用
- [npm install](https://docs.npmjs.com/cli/v6/commands/npm-install) で、dependencies に従って node_modules の下に依存関係を処理してくれる。
    - npm install のオプションは、[documents](https://docs.npmjs.com/cli/v6/commands/npm-install) を見て後々整理すべし
- [npm init](https://docs.npmjs.com/cli/v6/commands/npm-init) で作成すると package.json を用意してくれる
    - npx create-* で、各種 template を元に作れる。npm init *=> npx create-* って感じ
    - これ使わずに、いきなり package.json 書いて、npm install でもOK
    - template は [ここで。Link は React Native へ](https://www.npmjs.com/package/create-react-native-app)

# [Node.jsの使用開始](https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v3/developer-guide/getting-started-nodejs.html)
このチュートリアルは、npm init で作るわけではなく、自身で package.json を作成していく
これのおかげで、package.json の作り方とかがようやく整理ついた記念のチュートリアル

## [前提条件タスク](https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v3/developer-guide/getting-started-nodejs.html#getting-started-nodejs-prerequisites)
- npm インストール済み
- AWS SDK もOK
- 認証情報もOK。確認するなら %userprofile%\.aws\credentials を開けばOK。
    - [詳細はここ](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-files.html)

## [ステップ 1: Amazon S3 パッケージと依存関係をインストールします](https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v3/developer-guide/getting-started-nodejs.html#getting-started-nodejs-install-sdk)

- まずはプロジェクトフォルダを適当に作る
- て、フォルダ内へ移動して
- package.json を VS Code で開く

```bat: プロジェクトフォルダ作成
mkdir TryS3ByNode
cd TryS3ByNode
code package.json
```
貼り付けるコードはチュートリアルそのままで、保存して終了
```json: package.json
{
  "name": "aws-sdk-v3-iam-examples",
  "version": "1.0.0",
  "main": "index.js",
  "dependencies": {
   "@aws-sdk/client-s3": "^3.32.0"
  },
  "type": "module"
}
```
で、package.json をインストールさせる
```bat: インストール
npm install
```
依存関係の追加
ここの説明が、初心者に優しい説明。最初は意味不明ですが
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/a7323fc0-908f-49f1-d903-7ea222f6116e.png)

```bat: package インストール
npm install @aws-sdk/client-s3
```

## [ステップ 2: Node.js コードを記述する](https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v3/developer-guide/getting-started-nodejs.html#getting-started-nodejs-js-code)

- "libs" フォルダを作って
- current directory を lib へ
- library ファイルを VS Code で開いて編集

```bat: libraries の生成
mkdir lib
cd lib
code s3Client.js
```
- チューとリアルのコードをコピペ
- region を自分の環境に合わせて修正：ap-northeast-1　へ
```javascript: s3Client.js
import { S3Client } from "@aws-sdk/client-s3";
// Set the AWS Region.
const REGION = "ap-northeast-1"; //e.g. "us-east-1"
// Create an Amazon S3 service client object.
const s3Client = new S3Client({ region: REGION });
export { s3Client };
```

:::note info
sample code は [GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javascriptv3/example_code/nodegetstarted/src/libs/s3Client.js
) にもあるよーってことなので、後で見ないとね

:::

- で、再度 root に戻って
- メインのコードをVS Code で開く（作成）

```bat: sample.js の作成へ
cd ..
code sample.js
```

- いよいよ最後のコードをチュートリアルからコピペ

```javascript: sample.js
// Import required AWS SDK clients and commands for Node.js.
import { PutObjectCommand, CreateBucketCommand } from "@aws-sdk/client-s3";
import { s3Client } from "./libs/s3Client.js";

// Set the parameters
const params = {
  Bucket: "BUCKET_NAME", // The name of the bucket. For example, 'sample_bucket_101'.
  Key: "KEY", // The name of the object. For example, 'sample_upload.txt'.
  Body: "BODY", // The content of the object. For example, 'Hello world!".
};

const run = async () => {
  // Create an Amazon S3 bucket.
  try {
    const data = await s3Client.send(
        new CreateBucketCommand({ Bucket: params.Bucket })
    );
    console.log(data);
    console.log("Successfully created a bucket called ", data.Location);
    return data; // For unit tests.
  } catch (err) {
    console.log("Error", err);
  }
  // Create an object and upload it to the Amazon S3 bucket.
  try {
    const results = await s3Client.send(new PutObjectCommand(params));
    console.log(
        "Successfully created " +
        params.Key +
        " and uploaded it to " +
        params.Bucket +
        "/" +
        params.Key
    );
    return results; // For unit tests.
  } catch (err) {
    console.log("Error", err);
  }
};
run();
```



## [ステップ 3: 例の実行](https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v3/developer-guide/getting-started-nodejs.html#getting-started-nodejs-run-sample)

で、いよいよ動かす！

```bat: 起動
node sample.js
```

エラー解決へと :laughing: 

### モジュールが無い！？
> Error [ERR_MODULE_NOT_FOUND]: Cannot find module 'C:\Users\user\TryS3ByNode\libs\s3Client.js' imported from C:\Users\user\TryS3ByNode\sample.js

- チュートリアルでの libs の下のファイル名記述ミス修正
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/50855aff-dacb-e57c-8785-426c3d4a4fa3.png)

### 認証情報がおかしい
> Error CredentialsProviderError: Could not load credentials from any providers

%userprofile%\.aws\credentials で、[default] 定義が抜けていたので、既存のをコピーして [default] 作成

### バケット名が不正
> Error InvalidBucketName: The specified bucket is not valid.

- Default の名称 <code>BUCKET_NAME</code> も 例として記述されていた名称も <code>sample_bucket_101</code>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/f6c00878-adc9-d69c-fc15-c7b3a8120d2c.png)

初心に戻って、命名規則を見に行くと・・目が点
例が２つとも命名規則違反ですか :laughing: 

ってことで、"_" を "-" に修正して対処
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/44ef05d9-719a-a043-8d69-c6bedaf812cb.png)

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/bucketnamingrules.html

### バケット名重複
> Error BucketAlreadyExists: The requested bucket name is not available. The bucket namespace is shared by all users of the system. Please select a different name and try again.

"_" → "-" へ置換した以下の名称は、すでに使われてるってお話。まぁ、パーティション内ってなったらそうでしょうねぇ
ってことで、適当な名称にして対処

> sample-bucket-101

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/f7664cb1-809d-708e-94f7-7cada4156557.png)

### バケットは作られたが、ファイルが作られない
バケット作るだけのコードだった・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/968f370d-9ad3-90c8-6ec4-cbec3fdb90cb.png)

## 完了
で、ようやく完成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/fe577fd7-a383-0554-c6a4-af1cd1edb573.png)

# あとがき
チュートリアルで初めて上手くいった・・。

変化が激しい世界での長いチュートリアルはそのままじゃちゃんと動く奴は少ないんだなというのを改めて理解
で、技術に疎いと、それらの調査対処にも時間がかかるので、初期の立ち上がりは大変だなぁ・・と

今回は以下の理由でなんとかなったんだな、と
- Node.js + S3 という単純な世界
- 他のチュートリアルなどで、少しずつ対処できる範囲が広がった

次は、何にすべきか・・
- 止まってる cognito
- DynamoDB
- S3 でその他の機能確認
- React Native


なんかだんだん楽しくなってきた :laughing: