UMD版Hexabase JavaScript SDKを使ってファイルアップロードを行う

[Hexabase（ヘキサベース）](https://www.hexabase.com/)は企業においても安心して利用できるBaaS（Backend as a Service）を提供しています。多くのBaaSがそうであるように、主にフロントエンド開発者に利用してもらいたいと考えています。そこで現在、TypeScript SDKの開発が進められています。

元々TypeScriptで作られていることもあって、Next.jsやVue.jsなどでimportして利用することができます。しかし、もっと普通のWebアプリケーションなどで使う際には、CDN経由で利用したいと考える方もいるでしょう。そこで、UMD版Hexabase JavaScript SDKを作成しました。

今回は、そのUMD版Hexabase JavaScript SDKを使ってファイルアップロードを行うデモを紹介します。

## デモ

デモはこちらのURLで体験できます。

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/8a0e1281-57d8-e93e-fa80-7828def3bfb2.png)](https://jsfiddle.net/moongift/w8a1cv0h/51/)


## SDKの読み込み

SDKは下記URLで読み込めます。

```html
<script src="https://cdn.jsdelivr.net/npm/@hexabase/hexabase-js@latest/dist/umd/hexabase.min.js"></script>
```

バージョン指定する場合は、以下のようになります。メジャーバージョンが上がらない限りはlatest指定をお勧めします。

```html
<script src="https://cdn.jsdelivr.net/npm/@hexabase/hexabase-js@2.0.6/dist/umd/hexabase.min.js"></script>
```

モジュールとして使う場合には、以下のようになります。

```html
<script type="module">
import hexabase from 'https://cdn.jsdelivr.net/npm/@hexabase/hexabase-js@latest/+esm'
</script>
```

## SDKの初期化

SDKは以下のようコードで初期化します。これさえ終われば、後はTypeScriptと同じように使えます。

```javascript
const { HexabaseClient } = hexabase;
const client = new HexabaseClient();
```

## ファイルアップロードのデモ

ファイルアップロードのデモです。まずHTMLはBootstrapを使って、以下のように作成しています。

```html
<div class="container">
  <div class="row justify-content-md-center">
    <div class="col-10">
      <form>
        <div class="mb-3">
          <label for="formFile" class="form-label">Select file</label>
          <input class="form-control" type="file" name="photo" multiple accept="image/*">
        </div>
        <button type="submit" id="upload" class="btn btn-primary">アップロード</button>
      </form>
      <div id="result"></div>
      <br />
      <button type="submit" id="download" class="btn btn-success" disabled>ダウンロード</button>
      <div id="photos"></div>
    </div>
  </div>
</div>
```

### 初期設定

まず認証を行い、さらにHexabaseのワークスペースやプロジェクト、データストアを初期設定します。


```javascript
// 認証用のメールアドレスとパスワード
const email = 'demo5@moongift.jp';
const password = 'K4c%j%vzR7sQKS$u&Uo%';

// Hexabaseのワークスペース、プロジェクト、ワークスペースのID
const workspaceId = '644f6e5ab30d853869ec919f';
const projectId = '650a30501222568b1ae7a2c2';
const datastoreId = '650a306b15503cac1065f035';

// DOM情報
const uploadButton = document.querySelector('#upload');
const downloadButton = document.querySelector('#download');

// 処理内で使い回す
const params = {
  datastore: null,
  item: null,
};

// 初期化処理
(async () => {
  const res = await client.login({email, password});
  // ワークスペース・プロジェクト・データストアを取得
  await client.setWorkspace(workspaceId);
  const project = await client.currentWorkspace.project(projectId);
  params.datastore = await project.datastore(datastoreId);
  // アップロードボタンを押せるようにする
  uploadButton.disabled = false;
})();
```

### ファイルアップロード

ファイルはデータストアのアイテム（行相当）に紐付けてアップロードします。選択されているファイルをHexabaseのファイルオブジェクトに変換し、それをアイテムにセットします。フィールド名は `photos` としています。

```javascript
// フォーム送信時のイベント
document.querySelector('form').onsubmit = async (e) => {
  e.preventDefault();
  // リセット
  result.innerHTML = '';
  downloadButton.disabled = true;
  // 写真が選択されていなければ終了
  if (!e.target.photo.files || e.target.photo.files.length === 0) {
  	result.innerHTML = 'ファイルがありません';
    return true;
  }
  // 新規アイテムの作成
  const item = await params.datastore.item();
  
  // ファイルオブジェクトを作成
  const photos = Array.from(e.target.photo.files).map(photo => {
  	const file = item.file();
    file
        .set('name', photo.name)
	    .set('data', photo);
  	return file;
  });
  
  // 保存
  const res = await item
  	.set('Title', (new Date()).toDateString()) // タイトルをセット
    .set('photos', photos) // 写真を適用
    .save();
  // アイテムIDを保存
  params.item = item;
  // メッセージを出して、ダウンロードボタンを押せるようにする
  result.innerHTML = `アップロードしました。アイテムIDは ${item.id} です`;
  downloadButton.disabled = false;
};
```

### ファイルダウンロード

ファイルダウンロードは、アイテムからファイルオブジェクトを取得し、 `download` メソッドを呼び出すだけです。これでファイルオブジェクトの `data` プロパティにBlobデータが入ります。

Blobデータは `URL.createObjectURL` でURLに変換できます。これを `img` タグの `src` にセットすることで、画像を表示できます。

```javascript
// ダウンロードボタンを押した際のイベント
downloadButton.onclick = async (e) => {
  e.preventDefault();
  // 写真の入ったフィールドを取得
  const photos = params.item.get('photos');
  // 写真データの取得
  await Promise.all(photos.map(p => p.download()));
  // BlobをURLに変換
  const urls = photos.map(p => URL.createObjectURL(p.data));
  // DOMに表示
  document.querySelector('#photos').innerHTML = urls.map(url => `
  	<p><img src="${url}" width="300px" /></p>
  `).join('<br />');
}
```

## まとめ

UMD版Hexabase JavaScript SDKを使ってファイルアップロードを行うデモを紹介しました。UMD版Hexabase JavaScript SDKは、CDN経由で利用できるため、jQueryなど普通のWebアプリケーションでも利用できます。また、TypeScript SDKと同じように使えるため、TypeScript SDKを使っている方でも移行が容易です。

ぜひHexabaseを使ってWebアプリケーション開発を行ってください。

[Hexabase \| 新規事業向け開発・競争領域でのDX実現をサポート](https://www.hexabase.com/)