Hexabase Flutter SDKの使い方（フィールドの型対応）

[Hexabase（ヘキサベース）](https://www.hexabase.com/)は企業向けのBaaS（Backend as a Service）を提供しています。認証やデータストア、ファイルストレージ、リアルタイム通知などの機能があり、企業向けのシステム開発に必要な機能をまるっと提供しています。

APIはREST APIとGraphQLを提供しています。そのAPIをラップしたSDKも開発を進めています。SDKは現在、TypeScriptとDart向けに開発しています。Dart向けのSDKは、もちろんFlutterでも利用できます。

この記事ではFlutter SDKについてインストールと、フィールドの型に対応したので、その使い方を解説します。

## パッケージとソースコード

パッケージはpub.devで公開しています。

[hexabase | Flutter Package](https://pub.dev/packages/hexabase)

ソースコードはGitHubにて公開しています。ライセンスはMIT Licenseです。

[hexabase/hexabase-dart: Hexabase SDK for Dart & Flutter](https://github.com/hexabase/hexabase-dart)

## インストール

インストールは `dart pub get` で行えます。

```
dart pub get hexabase
```

## インポート

SDKをインポートします。

```dart
import 'package:hexabase/hexabase.dart';
```

## 初期化

まずインスタンスを作成します。

```dart
var client = Hexabase();
```

別なファイルで再度インポートした場合には、以下でインスタンスを取得してください。

```dart
var client = Hexabase.instance;
```

## アイテムの作成

データストア（クラウドデータベース）の行相当のデータがアイテムです。以下のようにして、新しいアイテムを作成します。

```dart
await client.setWorkspace('YOUR_WORKSPACE_ID');
var project = await client.currentWorkspace.project(id: 'YOUR_PROJECT_ID');
var datastore = await project.datastore(id: 'YOUR_DATABASE_ID');
// アイテムを作成
var item = await datastore.item();
```

## 利用できる型

Hexabaseで用意されているフィールド型は以下の通りです。ラベル、セパレータは管理画面上でのみ利用できます。

| 型名                 | Dartの型                                    | 更新可否 |
| -------------------- | ------------------------------------------- | -------- |
| テキスト             | String                                      | ○        |
| テキスト（ユニーク） | String                                      | ○        |
| 複数行テキスト       | String                                      | ○        |
| 選択肢               | String   \| HexabaseFieldOption             | ○        |
| ラジオ               | String   \| HexabaseFieldOption             | ○        |
| チェックボックス     | List&lt;String&gt;   \| List&lt;HexabaseFieldOption&gt; | ○        |
| 自動採番             | String                                      | ×        |
| 数値                 | int \| double                               | ○        |
| 計算式               | int \| double                               | ×        |
| 日付・時刻           | String \| DateTime                          | ○        |
| 添付ファイル         | List&lt;HexabaseFile&gt;                          | ○        |
| ユーザー             | List&lt;HexabaseUser&gt;                          | ○        |
| データベース参照     | HexabaseItem                                | ○        |
| ラベル               |                                             | ×        |
| セパレータ           |                                             | ×        |

## データの取得

既存データを取得した際の判定です。

```dart
// Title（常にテキスト）
var title = item.get('title');
expect(title is String, isTrue);

// テキスト
var testText = item.get('test_text');
expect(testText is String, isTrue);
// テキスト（ユニーク）
var testTextUnique = item.get('test_text_unique');
expect(testTextUnique is String, isTrue);
// 複数行テキスト
var testTextarea = item.get('test_textarea');
expect(testTextarea is String, isTrue);
// 選択肢
var testSelect = item.get('test_select');
expect(testSelect is HexabaseFieldOption, isTrue);
// ラジオ
expect(testSelect.value is String, isTrue);
var testRadio = item.get('test_radio');
expect(testRadio is HexabaseFieldOption, isTrue);
expect(testRadio.value is String, isTrue);
// チェックボックス
var testCheckbox = item.get('test_checkbox');
expect(testCheckbox is List, isTrue);
expect(testCheckbox[0] is HexabaseFieldOption, isTrue);
expect(testCheckbox[0].value is String, isTrue);
// 自動採番
var testAutonumber = item.get('test_autonum');
expect(testAutonumber is String, isTrue);
// 数値
var testNumber = item.get('test_number');
expect(testNumber is int, isTrue);
// 日付
var testDatetime = item.get('test_datetime');
expect(testDatetime is DateTime, isTrue);
// 添付ファイル
var testFile = item.get('test_file');
expect(testFile is List, isTrue);
expect(testFile[0] is HexabaseFile, isTrue);
// ユーザー
var testUsers = item.get('test_users');
expect(testUsers is List, isTrue);
expect(testUsers[0] is HexabaseUser, isTrue);
// データベース参照
var testDslookup = item.get('test_dslookup');
expect(testDslookup is HexabaseItem, isTrue);
expect(testDslookup.datastore is HexabaseDatastore, isTrue);
```

## 値のセット

アイテムに値をセットする場合にも、型に適合している必要があります。エラーはすべてExceptionとして返されます。

```dart
// 新規アイテム
var item = await datastore.item();
// フィールドが存在しない
try {
	item.set('name', 100);
	expect(false, isTrue);
} catch (e) {
	expect(e is Exception, isTrue);
}
// テキスト型に数値をセット
try {
	item.set('test_text', 100);
	expect(false, isTrue);
} catch (e) {
	expect(e is Exception, isTrue);
}
// 数値型にテキストをセット
try {
	item.set('test_number', 'test_number');
	expect(false, isTrue);
} catch (e) {
	expect(e is Exception, isTrue);
}
// 自動採番にテキストをセット（自動採番は[0-9]+のみ）
try {
	item.set('test_autonum', 'test_text_unique');
	expect(false, isTrue);
} catch (e) {
	expect(e is Exception, isTrue);
}
// 日付型にテキストをセット
try {
	item.set('test_datetime', 'test_text_unique');
	expect(false, isTrue);
} catch (e) {
	expect(e is Exception, isTrue);
}
// 日付型に、日付として解釈できる文字列をセット（これはOK）
item.set('test_datetime', "2020-01-01 00:00:00");
var d = item.get<DateTime>('test_datetime'); // 取得すると、DateTime型になっている
expect(d is DateTime, isTrue);
```

## まとめ

HexabaseのFlutter SDKは、管理画面で設定したフィールド型に対応しています。そのため、アプリケーション側で型を適切に解釈した実装が可能です。文字列と数字、日付など間違った値を設定してしまうのを避けられます。

HexabaseのFlutter SDKを使って、堅牢なWebアプリケーションを開発してください。

[hexabase \| Dart package](https://pub.dev/packages/hexabase)