ローコードプラットフォームSPIRALのAPIを利用する（一覧表データの取得）

[SPIRAL](https://www.spiral-platform.co.jp/)は、主にエンタープライズ向けのローコードプラットフォームになります。ローコードプラットフォームなので、プログラミング知識がなくともWebアプリケーションを開発できるのが魅力です。

SPIRALでは、自社のシステムや外部システムと連携する場合を想定して、APIが公開されています。今回は、そのAPIを利用して、一覧表データを取得する流れを解説します。

## 注意点

SPIRALでは、SPIRAL内部で動作するアカウント内APIと、外部APIの2種類があります。アカウント内APIでは、簡単に操作できるPHP SDKがありますが、外部公開はされていません。そのため、今回はPHPの `file_get_contents` などを使ってAPI操作をしています。

## 準備

### APIトークンの取得

SPIRALの管理画面で、APIトークンを作成します。ダッシュボードの開発メニュー内のAPIトークンにて、新しいAPIトークンを作成します。

![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/c801e3c2-5007-40d1-a9cf-9838b9df6758.png)


作成後に入手できるAPIトークンと、APIトークンシークレットをメモしておきます。

### データベースの作成

今回は、作成したのは通常DBになります。SPIRALでは、この他8種類のデータベースが利用できます。

[【機能紹介】各種DB \| SPIRAL ナレッジサイト](https://knowledge.spirers.jp/article/design/detail/730)

データベースの名前は `testdata` としました。作成したフィールドは以下の通りです。

| フィールド名   | サンプル値           | 型                                 | 差し替えキーワード |
| -------------- | -------------------- | ---------------------------------- | ------------------ |
| 名前           | テキスト30文字前後   | テキストフィールド(64 bytes)       | name               |
| フリガナ       | テキスト30文字前後   | テキストフィールド(32 bytes)かな   | furigana           |
| メールアドレス | aaa@bbb.cc.dd        | メールアドレス（大・小文字を無視） | mail               |
| 性別           | 男性、女性           | 性別                               | gender             |
| 年齢           | 0～99                | 数値                               | ageyo              |
| 誕生日         | yyyy年mm月dd日       | 日付（○年○月○日）                  | birthday           |
| 婚姻状況       | 独身                 | テキストフィールド(32 bytes)       | maritalStat        |
| 都道府県       | プルダウンから選択   | 都道府県                           | prefecture         |
| 電話番号       | 09012345678          | 電話番号                           | telephone          |
| キャリア       | docomo、au、SoftBank | テキストフィールド(32 bytes)       | carrier            |
| スタイル       | スタイル             | テキストフィールド(32 bytes)       | style              |

### マイエリアの作成

管理画面の `Web` にある `マイエリア` から、新しいマイエリアを作成します。会員専用のページの集まりのことです。マイエリア機能を用いることで、ノーコードで会員専用ページや会員専用アンケート、会員情報変更ページ等を構築できます。

![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/5741ac5a-da21-497c-82fb-b689f8a352f8.png)


認証を行う際には、このマイエリアが必要になりますので、新しく作成します。今回は `my_area` という名前で作成しました。

### 一覧表の作成

一覧表はWeb > 一覧表・単票から作成します。一覧表としてデータベースを選択し、さらに検索フォームを作成します。今回はsearch1という検索フォームを作成しています。

![image3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/eeccf58b-dcd6-4953-afc6-e7aae02ca61d.png)


## コードについて

今回はPHPで作成しています。
### APIトークンの保存

APIトークンとシークレット、ログイン用のIDとパスワードは、環境変数に保存します。以下のように `.env` ファイルを作成し、トークンを保存します。

```env
API_TOKEN=your_api_token
API_TOKEN_SECRET=your_api_token_secret
ID=use@smp.ne.jp
PASSWORD=your_password
```

.env の読み込みは `vlucas/phpdotenv` を使っています。インストールは `composer` で行います。

```bash
composer require vlucas/phpdotenv
```

次に、PHPのコード内で `.env` を読み込みます。

```php
require_once __DIR__ . "/vendor/autoload.php";

$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
```

### APIリクエストURLの取得

APIでリクエストするURLは、以下の手順で取得します。

```php
// ロケータのURL (変更の必要はありません)
$locator = "https://www.pi-pe.co.jp/api/locator";

// スパイラルの操作画面で発行したトークンを設定します。
$TOKEN = $_ENV['API_TOKEN'];
$SECRET = $_ENV['API_TOKEN_SECRET'];

// API用のHTTPヘッダ
$api_headers = array(
    "X-SPIRAL-API: locator/apiserver/request",
    "Content-Type: application/json; charset=UTF-8",
);

// 送信するJSONデータを作成
$parameters = array();
$parameters["spiral_api_token"] = $TOKEN; //トークン

// 送信用のJSONデータを作成します。
$json = json_encode($parameters);

// curlライブラリを使って送信します。
$curl = curl_init($locator);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $json);
curl_setopt($curl, CURLOPT_HTTPHEADER, $api_headers);
curl_exec($curl);

// エラーがあればエラー内容を表示
if (curl_errno($curl)) echo curl_error($curl);
$response = curl_multi_getcontent($curl);
curl_close($curl);
$response_json = json_decode($response, true);

// サービス用のURL
$APIURL = $response_json['location'];
```

この時のレスポンスは以下のようになっています。詳細は[SPIRAL ver\.1 API リファレンス](https://support.smp.ne.jp/api/index.html#operation/locatorApiserver)にて確認してください。

```json
{
  "code": 0,
  "message": "OK",
  "location": "https://（APIサーバ）/api/service",
  "default_version": 2,
  "supported_version": [1, 2],
  "use_client_crt": "f"
}
```

`location` にAPIサーバのURLが入っています。

### ログイン

ログイン処理です。この時には、前述のマイエリアの名前が必要です。

```php
// ログインリクエスト
$api_headers = array(
    "X-SPIRAL-API: area/login/request",
    "Content-Type: application/json; charset=UTF-8",
);

// リクエストデータを作成
$parameters = array();
$parameters["spiral_api_token"] = $TOKEN; //トークン
$parameters["passkey"] = time(); //エポック秒
$parameters["my_area_title"] = "my_area";
$parameters["id"] = $_ENV['ID'];
$parameters["password"] = $_ENV['PASSWORD'];
$parameters["url_type"] = "2";

// 署名を付けます
$key = $parameters["spiral_api_token"] . "&" . $parameters["passkey"];
$parameters["signature"] = hash_hmac('sha1', $key, $SECRET, false);

// JSON形式にエンコードします。
$json = json_encode($parameters);
echo "===> area/login\n";
echo $json . "\n\n";

// POSTで送信します。
$stream = stream_context_create(
    array('http' => array(
        'method' => 'POST',
        'protocol_version' => '1.0',
        'header' => $api_headers,
        'content' => $json
    ))
);

// レスポンスデータ読み込み
$response = file_get_contents($APIURL, false, $stream);
$response_json = json_decode($response, true);

// セッションID
$jsessionid = $response_json['jsessionid'];
```

セッションIDは認証状態を維持する際に必要です。ログイン時のレスポンスは以下のようなJSONです。

```json
{
  "code": 0,
  "message": "OK",
  "jsessionid": "0323029CFD30EFA31C00912FC11F6D6B",
  "session_expire": 1603250145,
  "url": "https://www.example.com/area/servlet/area.MyPageBundle?MyPageID=f54...7l1",
  "auto_login_cookie": "r10...ded",
  "auto_login_limit": 1603334087
}
```

### データの取得

次にマイエリア、検索フォームを指定してデータを取得します。検索条件として、 `gender = 1` を指定しています。

```php
// API用のHTTPヘッダ
$api_header = "";
$api_header .= "X-SPIRAL-API: table/data/request\r\n";
$api_header .= "Content-Type: application/json; charset=UTF-8\r\n";

// 送信するJSONデータを作成
$parameters = array();
$parameters["spiral_api_token"] = $TOKEN;
$parameters["my_area_title"] = "my_area";
$parameters["search_title"] = "search1";
$parameters["passkey"] = time();

// 検索条件
$parameters["search_condition"] = array(
    array("name" => "gender", "value" => "1"),
);

// セッションIDを付けます
$response_json = json_decode($response, true);
$parameters["jsessionid"] = $response_json["jsessionid"];

// 署名を付けます
$key = $parameters["spiral_api_token"] . "&" . $parameters["passkey"];
$secret = $SECRET;
$parameters["signature"] = hash_hmac('sha1', $key, $secret, false);
$json = json_encode($parameters);
echo "==> TABLE REQUEST (JSON)\n";
echo $json . "\n\n";

// POSTで送信します。
$stream = stream_context_create(
    array('http' => array(
        'method' => 'POST',
        'protocol_version' => '1.0',
        'header' => $api_header,
        'content' => $json
    ))
);

// レスポンスデータ読み込み
$response = file_get_contents($api_url, false, $stream);
```

結果は以下のように、検索結果が返ってきます。

```json
{
  "code": "0",
  "jsessionid": "7FE...EB6",
  "data": [
    ["11","山崎 加奈","おおた あきら","kumiko98@inoue.com","NA","18",""],
    ["12","高橋 健一","きむら みき","gota@murakami.jp","NA","34",""],
    :
    ["19","山本 七夏","さいとう やすひろ","yutaaoki@hotmail.com","NA","39",""],
    ["20","松本 裕太","やまだ あすか","ryosukekato@gmail.com","NA","30",""]
  ],
  "count": "200",
  "header": ["id","名前","フリガナ","メールアドレス","性別","年齢",""],
  "message":"OK"
}
```

### ログアウト

後はログアウトして完了です。

```php
// ログアウトリクエスト
$api_headers = array(
    "X-SPIRAL-API: area/logout/request",
    "Content-Type: application/json; charset=UTF-8",
);

// リクエストデータを作成
$parameters = array();
$parameters["spiral_api_token"] = $TOKEN; //トークン
$parameters["passkey"] = time(); //エポック秒
$parameters["my_area_title"] = "my_area";

// セッションIDを付けます
$parameters["jsessionid"] = $jsessionid;

// 署名を付けます
$key = $parameters["spiral_api_token"] . "&" . $parameters["passkey"];
$parameters["signature"] = hash_hmac('sha1', $key, $SECRET, false);

// JSON形式にエンコードします。
$json = json_encode($parameters);

// POSTで送信します。
$stream = stream_context_create(
    array('http' => array(
        'method' => 'POST',
        'protocol_version' => '1.0',
        'header' => $api_headers,
        'content' => $json
    ))
);

// レスポンスデータ読み込み
$response = file_get_contents($APIURL, false, $stream);
```

レスポンスのJSONは、以下のようになります。

```json
{
  "code": 0,
  "message": "OK",
  "url": "https://www.example.com/area/servlet/are...7l1",
  "jsessionid": "032...D6B",
  "auto_login_cookie": "r109...ded",
  "auto_login_limit": 1603334087
}
```
## まとめ

今回はSPIRALのAPIを利用して、一覧表・単票のデータ表示を行う流れを紹介しました。一覧表・単票は管理画面から使うこともできますし、単票を公開したり、こうしてAPIから操作もできます。ぜひシステム連携に役立ててください。

1分あたりのAPIのリクエスト数は、契約によって上限があります。ご注意ください（詳細は[APIのリクエスト数制限を知りたい SPIRAL ver\.1 サポートサイト](https://support.smp.ne.jp/faq/api-faq/f0094/)にて）。

[API SPIRAL ver\.1 サポートサイト](https://support.smp.ne.jp/api-manuals/)