Storage Browser for Amazon S3をためしてみた

:::note warn
2024 年 12月 にGAされています。こちらの記事はプレビュー版です。GAの記事は下記の通り。
:::

https://qiita.com/MK_Tech/items/c931ce97d33cbedde002

## はじめに

2024 年 9 月 5 日に「Storage Browser for Amazon S3 for your web applications」がアルファリリースされました。

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

S3 は私の推しのサービスです ⭐️

記事を見ると Amplify で構築できそうだったので、さっそく試してみました。

## Storage Browser for Amazon S3 とは

Web アプリに S3 でのファイルブラウズ機能を追加し、データ参照アップロードやダウンロード機能を提供するもの。

Amplify UI ライブラリの一部として提供することを予定しているようです。

https://github.com/aws-amplify/amplify-ui/issues/5731

## 導入方法

既存の S3 でも導入できるようですが、今回は Amplify Gen2 で イチ から構築する方法を試してみます。

:::note alert
2024 年 9 月 7 日　現在のライブラリを利用して構築しています。。アルファリリースなので今後変更される可能性があります。
利用時は注意です。
:::


記事の最後に実際に構築した [Git リポジトリのリンク](#まとめ)もありますのでぜひ参照してください!

### Amplify Gen2 のセットアップ

今回は Next で構築するので、下記の Amplify ドキュメントを参考に Next App Router でセットアップします。

https://docs.amplify.aws/nextjs/start/quickstart/nextjs-app-router-client-components/

#### Next のテンプレートを自身のリポジトリにコピー

Create repository from template をクリックするとテンプレートからリポジトリを作成できます。

![preview-s3-browser-alpha-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831737/3a1ae5b5-e057-8fc8-e22f-034934d04702.png)

適当な名前にしてリポジトリを作成します。

#### コピーしたリポジトリをローカルにクローン

```sh
git clone https://github.com/<Gitアカウント>/<リポジトリ名>.git
```

#### プロジェクトの初期化

プロジェクトに移動してパッケージをインストール。

```sh
cd <リポジトリ名> && npm install
```

StorageBrowser に必要なパッケージを追加します。

```sh
npm i --save @aws-amplify/ui-react-storage@storage-browser aws-amplify@storage-browser
```

これで準備完了。

### バックエンドの不要なリソースを削除する

テンプレート では Data リソースがあるので削除。

```diff_typescript
// amplify/backend.ts
  import { defineBackend } from '@aws-amplify/backend';
  import { auth } from './auth/resource.js';
- import { data } from './data/resource.js';

defineBackend({
  auth,
- data
});
```

amplify ディレクトリの data は削除しても OK。

### Amplify Gen2 で S3 バケット を作成する。

Gen2 では storage ディレクトリにリソースを定義することで S3 バケット を定義できます。

![preview-s3-browser-alpha-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831737/398a606b-5e09-fbcd-98c6-1121ea5c9c7e.png)

#### resouce.ts に S3 バケットの設定を定義

resource.ts に S3 バケットの設定を定義していく。今回は[issues](https://github.com/aws-amplify/amplify-ui/issues/5731)にそって作成する。

```typescript
//amplify/storage/resource.ts
import { defineStorage } from "@aws-amplify/backend";

export const storage = defineStorage({
  name: "myProjectFiles",
  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"]),
    ],
  }),
});
```

サンプルに通りだと myProjectFiles という バケット が作成されます。名前はなんでも OK。
Cognito の権限に合わせてアクセス制御も設定できます。

Gen2 では直感的に定義できてカスタマイズも容易ですね。

#### backend.ts に storage の定義を追加する。

先ほど定義した storage を backend.ts に追加します。

```diff_typescript
// amplify/backend.ts
  import { defineBackend } from '@aws-amplify/backend';
  import { auth } from './auth/resource.js';
+ import { storage } from './storage/resource.js';

defineBackend({
  auth,
+ storage,
});
```

これにて Backend の準備が整いました。

### Sandbox を立ち上げる

sandbox を立ち上げることでてリソースが作成される。

```sh
npx ampx sandbox
```

これにて backend は完了です 🚀

### フロントエンドを修正する

やることは大き 3 つあります。

1. CSS のインポート
2. 各コンポーネントの追加
3. 不要な CSS の削除

#### CSS のインポート

Template では Amplify UI を利用する設定があらかじめ行われているが、今回は CSS を追加する必要がある。

```diff_typescript
// app/page.ts
  import "@aws-amplify/ui-react/styles.css";
+ import "@aws-amplify/ui-react-storage/storage-browser-styles.css";
```

:::note info
CSS の適用を忘れてしますと UI が崩れるので要注意です！
また、Next テンプレートのデフォルトの CSS は無効にします。
:::

#### 各コンポーネントのインポート

StorageBrowser と Authenticator をインポート
ログアウトボタンも実装したかったので Button も追加している。

```typescript
// app/page.ts
import { StorageBrowser } from "@aws-amplify/ui-react-storage";
import { Authenticator, Button } from "@aws-amplify/ui-react";
```

StorageBrowser の props とそれぞれのコンポーネントを定義します。

```typescript
// app/page.ts
const defaultPrefixes = [
  "public/",
  (identityId: string) => `protected/${identityId}/`,
  (identityId: string) => `private/${identityId}/`,
];

export default function App() {
  return (
    <Authenticator>
      {({ signOut }) => (
        <>
          <Button onClick={signOut}>Sign Out</Button>
          <StorageBrowser defaultPrefixes={defaultPrefixes} />
        </>
      )}
    </Authenticator>
  );
}
```

<details><summary>コード全体はこちら</summary>

```typescript
// app/page.ts
"use client";

import { Amplify } from "aws-amplify";
import outputs from "@/amplify_outputs.json";
import "@aws-amplify/ui-react/styles.css";
import "@aws-amplify/ui-react-storage/storage-browser-styles.css";

Amplify.configure(outputs);

import { StorageBrowser } from "@aws-amplify/ui-react-storage";
import { Authenticator, Button } from "@aws-amplify/ui-react";

const defaultPrefixes = [
  "public/",
  (identityId: string) => `protected/${identityId}/`,
  (identityId: string) => `private/${identityId}/`,
];

export default function App() {
  return (
    <Authenticator>
      {({ signOut }) => (
        <>
          <Button onClick={signOut}>Sign Out</Button>
          <StorageBrowser defaultPrefixes={defaultPrefixes} />
        </>
      )}
    </Authenticator>
  );
}
```

</details>

#### 不要な CSS を削除する

デフォルトの CSS は不要なので消しちゃいます。

```diff_typescript
// app/page.ts
- import "./../app/app.css";
```

```diff_typescript
// app/layout.ts
- import "./app.css";
```

これにてフロントの実装も完了 🚀

## テスト

テスト環境を立ち上げてローカルサーバーへアクセス。

```sh
npm run dev
```

ログイン画面が表示されれば成功。アカウントのを作成してログインします。

![preview-s3-browser-alpha-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831737/1d00a3bd-76d2-dde5-65d9-f2b7209ddafe.png)

アクセスできるストレージが表示されます。

![preview-s3-browser-alpha-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831737/39db3df0-1030-30b7-d3d8-51c122024424.png)

フォルダの作成やファイルの追加ができますね！

![preview-s3-browser-alpha-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831737/c5fd1a8d-eba9-f151-d8f5-3a0346e77c29.png)

簡単に S3 のブラウザアプリが作成できました 🚀

## まとめ

ファイルなどの削除機能はなさそう。ただ Amplify Gen2 を使えばアクセス制御も直感的に素早くおこなえ、業務でも利用できそうな予感がします。今後の発展が、すごく楽しみなコンポーネントになりそうです ❤️

今回のコード全体は GitHub に置います。
よければ参考にしてください。

#### GitHub のサンプル 🔗

https://github.com/mkdev10/amplify-next-storage-browser-test