Storage Browser for Amazon S3が一般提供されたので使ってみた

# はじめに
Amazon S3に保存されたデータを簡単にUI表示できる「Storage Browser for S3」の一般提供が開始されました。

https://aws.amazon.com/jp/about-aws/whats-new/2024/12/storage-browser-amazon-s3/

AWS News Blogの方に使い方が載っていたので、実際に試してみたいと思います。

https://aws.amazon.com/jp/blogs/aws/connect-users-to-data-through-your-apps-with-storage-browser-for-amazon-s3/

# Storage Browser for Amazon S3って？
Storage Browser for Amazon S3は、WebアプリケーションのUIコンポーネントとして組み込むことで、Amazon S3のデータを簡単に可視化し、以下のような管理操作を行うことができます。
 - データの参照
 - データのダウンロード
 - データのアップロード
 - データの削除
 - 検索
 - など

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560123/a08ca378-eb04-1cf9-256a-03e04f97e829.png)


### ユースケース
従来は、Amazon S3 のデータをエンドユーザに公開する場合、独自のUIを開発して、SDKやAPIを使用してS3からデータを取得するなどの実装が必要でした。
Storage Browser for Amazon S3を使えば、少ないコードで簡単に実装できます。

### OSSなので無料で使える
Storage Browser for Amazon S3は、AWS Amplify UI Reactに組み込まれており、オープンソースとして無料で使用できます。ただし、Amazon S3などのUI以外で使用するAWSサービスには別途料金が発生します。

https://www.npmjs.com/package/@aws-amplify/ui-react-storage

:::note info
**補足1：AWS Amplifyとは**
AWS Amplifyは、フロントエンドとバックエンドの両方を簡単に構築、ホスティングできるAWSサービスです。そのため開発者はフルスタックでアプリケーションを構築できます。
:::

:::note info
**補足2：AWS Amplify UI Reactとは**
AWS Amplify UI Reactは、AWSが提供するオープンソースの UI ライブラリです。
開発者はUIからAWSのAPIやSDKを直接呼び出す複雑な実装をせずに、WSサービスとUIを簡単に連携させることができます。
:::                                        

# 実際に使ってみる

参考にするAWS News Blog
https://aws.amazon.com/jp/blogs/aws/connect-users-to-data-through-your-apps-with-storage-browser-for-amazon-s3/

### 前提：エンドユーザの認証/承認
エンドユーザがAmazon S3へアクセスするためには、認証/承認が必要です。主に以下の３つの方法がありますが、今回は「AWS Amplify Auth(Amazon Cognito)」を使用します。

1. **AWS Amplify Auth(Amazon Cognito)**
    - ユースケース：お客様やビジネスパートナーにAmazon S3のデータを見せたい時
2. **AWS IAM Identity Center**
    - ユースケース：会社の従業員全員がS3のデータを見られるようにしたい時
3. **Amazon S3 Access Grantsでの IAM ロール**
    - ユースケース：特定の人やプログラムにS3のデータを見せたい時       

## 前提：Viteで空のプロジェクトを作る
参考記事ではNext.jsを使用していますが、今回はアプリケーションをシンプルに作りたいので、Viteを使用して簡単なアプリケーションを作成します。

:::note info
**Viteについて**
Viteは、モダンなWebアプリケーション開発のための高速なビルドツールです。
従来のビルドツールよりも高速な開発サーバーの起動と、効率的な本番ビルドを提供し、React、Vue、Svelteなど様々なフレームワークをサポートしています。
:::

```
> npm create vite@latest

Need to install the following packages:
create-vite@6.0.1
Ok to proceed? (y) y
√ Project name: ... storage_browser_for_s3_sample
√ Select a framework: » React
√ Select a variant: » JavaScript

Scaffolding project in D:\20241202_Storage_Browser_for_Amazon_S3\storage_browser_for_s3_sample...

Done. Now run:

  cd storage_browser_for_s3_sample
  npm install
  npm run dev
```

```:ディレクトリ構成
storage_browser_for_s3_sample/
│
├── node_modules/
├── public/
├── src/
│   ├── assets/
│   ├── App.css
│   ├── App.jsx
│   ├── index.css
│   └── main.jsx
│
├── index.html
├── eslint.config.js
├── package-lock.json
├── package.json
├── vite.config.js
└── README.md
```

## Step1. 必要なライブラリのインストール
以下のライブラリをインストールします。
- @aws-amplify/ui-react-storage
- aws-amplify

```
> npm install @aws-amplify/ui-react-storage aws-amplify

added 553 packages, and audited 554 packages in 3m

111 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
```

## Step2. AWS Amplifyの初期化
AWS Amplifyを初期化します。

```
> npm create amplify@latest

Need to install the following packages:
create-amplify@1.0.6
Ok to proceed? (y) y
? Where should we create your project? .

Installing devDependencies:
 - @aws-amplify/backend
 - @aws-amplify/backend-cli
 - aws-cdk@^2
 - aws-cdk-lib@^2
 - constructs@^10.0.0
 - typescript@^5.0.0
 - tsx
 - esbuild

Installing dependencies:
 - aws-amplify

✔ DevDependencies installed
✔ Dependencies installed
✔ Template files created
Successfully created a new project!

Welcome to AWS Amplify!
 - Get started by running npx ampx sandbox.
 - Run npx ampx help for a list of available commands.

Amplify collects anonymous telemetry data about general usage of the CLI. Participation is optional, and you may opt-out by using npx ampx configure telemetry disable. To learn more about telemetry, visit https://docs.amplify.aws/react/reference/telemetry
```

```:ディレクトリ構成
storage_browser_for_s3_sample/
│
├── amplify/
│   ├── auth/
|   |   └── resource.ts
│   ├── data/
|   |   └── resource.ts
│   ├── backend.ts
│   ├── package.json
│   └── tsconfig.json
├── node_modules/
├── public/
├── src/
│   ├── assets/
│   ├── App.css
│   ├── App.jsx
│   ├── index.css
│   └── main.jsx
│
├── index.html
├── eslint.config.js
├── package-lock.json
├── package.json
├── vite.config.js
└── README.md
```

### Step3. Amplify Storageを設定する
Amplify Storageは、Amplifyを使用してAmzon S3を構築する際の機能です。
resource.tsファイルを新規作成し、Amazon S3とアクセス許可を定義します。

```ts:resorce.ts
import { defineStorage } from '@aws-amplify/backend';

export const storage = defineStorage({
  name: 'amplifyTeamDrive',
  access: (allow) => ({
    'public/*': [
      allow.guest.to(['read']),
      allow.authenticated.to(['read', 'write', 'delete']),
    ],
    'protected/{entity_id}/*': [
      allow.authenticated.to(['read']),
      allow.entity('identity').to(['read', 'write', 'delete'])
    ],
    'private/{entity_id}/*': [
      allow.entity('identity').to(['read', 'write', 'delete'])
    ]
  })
});

```
既存のbackend.tsでresource.tsをimportして、defineBackendにstorageを追加します。

```ts:backend.ts
import { defineBackend } from '@aws-amplify/backend';
import { auth } from './auth/resource';
import { data } from './data/resource';
import { storage } from './storage/resource'; // 追加

/**
 * @see https://docs.amplify.aws/react/build-a-backend/ to add storage, functions, and more
 */
defineBackend({
  auth,
  data,
  storage // 追加
});

```

サンドボックス環境にデプロイします。
```
npx ampx sandbox --profile <任意のプロファイル名>
```

:::note info
**AWS Amplifyのサンドボックス環境**
実際のAWSアカウント上に開発用リソースを作成しますが、本番環境とは分離された開発・テスト環境を構築できる機能です。
:::

#### 参考

https://docs.amplify.aws/react/build-a-backend/storage/set-up-storage/

https://docs.amplify.aws/react/build-a-backend/storage/authorization/

### Step4. アプリ側でAmplifyを設定
./srcフォルダに以下のファイルを新規作成し、アプリ側のAmplifyの設定を行います。

```ts:amplify_setup.js
import {
  createAmplifyAuthAdapter,
  createStorageBrowser,
} from '@aws-amplify/ui-react-storage/browser';
import "@aws-amplify/ui-react-storage/styles.css";[]
import config from '../amplify_outputs.json';
import { Amplify } from 'aws-amplify';

Amplify.configure(config);

export const { StorageBrowser } = createStorageBrowser({
  config: createAmplifyAuthAdapter(),
});

```
作成したamplify_setup.jsをApp.jsxでimportしてReactのコンポーネントとして組み込みます。

```js:App.js
import { StorageBrowser } from './amplify_setup';

function App() {

  return (
    <div className='p-4'>
      <h1>Amplify UI test</h1>
      <div className='mt-4'>
        <StorageBrowser/>
      </div>
    </div>
  )
}

export default App

```

### Step5. ローカルでアプリを実行
今の状態でアプリをViteでローカル実行してみます。
```
> npm run dev

  VITE v6.0.1  ready in 641 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help
```

「http://localhost:5173/」 にアクセスすると、以下のようにAmazon S3のバケットが表示されました。しかし、今のままだと未認証のユーザ扱いなので、ファイルの参照しかできません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560123/4c6c1420-ddaf-1241-c2b1-a2ee4fed8fa4.png)

### Step7. 認証機能も追加してみる
せっかくなのでユーザ登録/ログイン/ログアウトの画面も追加します。

必要なライブラリをインストールします。
```
> npm add @aws-amplify/ui-react
```

ユーザ登録/ログイン/ログアウトの画面を追加できるAuthenticatorコンポーネントを追加します。

```js:App.js
import { StorageBrowser } from './amplify_setup';
import { Authenticator } from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';

function App() {

  const StorageApp = () => {
    return (
      <div className='p-4' >
        <div className='mt-4'>
          <StorageBrowser/>
        </div>
      </div>
    );
  };

  const AuthenticatorApp = () => {
    return (
      <Authenticator>
        {({ signOut, user }) => (
          <main style={{ width: "100%"}}>
            <h4>userName {user?.username}</h4>
            <button onClick={signOut}>Sign out</button>
            <StorageApp/>
          </main>
        )}
      </Authenticator>
    );
  };

  return (
    <AuthenticatorApp/>
  )
}

export default App

```

必須ではないですが、少しスタイルをいじって中央寄せにします。
```css:index.css
/* 省略 */

body {
  margin: 0;
  display: flex;
  justify-content: center; /* 追加 */
  place-items: center;
  min-width: 320px;
  min-height: 100vh;
}

/* 省略 */
```


再度、画面を開いてみると、SignInの画面が表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560123/c214d968-6bf4-fb51-b6ae-055456a8ce4d.png)

次は、Create Accountのメニューを開いて、任意のメールアドレスとパスワードを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560123/a26ab4b1-c784-ba85-800f-7f8ec5169b0d.png)

入力したメールアドレスに検証コード(6桁)が届くので画面で入力します。
ユーザ登録に成功すると、S3の画面が出ました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560123/340d526f-b5df-6568-128e-8c99f6be04fb.png)

既にAmazon Cognitoで認証済みのユーザであるため、「Create folder」や「Upload」といった機能も使えるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560123/8e22c923-f3c8-16a9-f573-58c4f00cfa6b.png)

※ライブラリのバージョン情報ということで、package.jsonを張っておきます。
<details><summary>package.json</summary>

```json
{
  "name": "storage_browser_for_s3_sample",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "lint": "eslint .",
    "preview": "vite preview"
  },
  "dependencies": {
    "@aws-amplify/ui-react": "^6.7.1",
    "@aws-amplify/ui-react-storage": "^3.5.0",
    "aws-amplify": "^6.10.0",
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  },
  "devDependencies": {
    "@aws-amplify/backend": "^1.8.0",
    "@aws-amplify/backend-cli": "^1.4.2",
    "@eslint/js": "^9.15.0",
    "@types/react": "^18.3.12",
    "@types/react-dom": "^18.3.1",
    "@vitejs/plugin-react": "^4.3.4",
    "aws-cdk": "^2.171.1",
    "aws-cdk-lib": "^2.171.1",
    "constructs": "^10.4.2",
    "esbuild": "^0.24.0",
    "eslint": "^9.15.0",
    "eslint-plugin-react": "^7.37.2",
    "eslint-plugin-react-hooks": "^5.0.0",
    "eslint-plugin-react-refresh": "^0.4.14",
    "globals": "^15.12.0",
    "tsx": "^4.19.2",
    "typescript": "^5.7.2",
    "vite": "^6.0.1"
  }
}

```
</details>


### 後始末
最後に以下のコマンドを実行して、サンドボックス環境を削除します。
```
npx amplify sandbox delete --profile {aws-profile}
```

# まとめ
Storage Browser for Amazon S3を活用することで、簡単にAmazon S3を操作できるUIを作ることができました。

自力で実装しようとすると、API呼び出し処理を書き、API結果の処理を行い、エラーの場合の処理を実装して、結果をUIに表示して...と複雑になりがちな処理を隠蔽してくれるので、非常に助かると感じました。

今後のAWSの展開として、Amazon S3以外のストレージ系サービスでもUIコンポーネントが提供される流れなんですかね。AWS re:Invent 2024が絶賛開催中なので、他にもフロントエンド系の新しい発表があれば試してみたいと思います。