Xplenty中級編 Part10：XplentyのRest APIによる既存業務との連携(2)

# はじめに
専門ETLツールである弊社のXplentyは、ノーコード／ローコードツールとしてデータパイプラインの構築に対してITバッググラウンドが浅い方のためにGUI環境を提供しております。また、Xplentyの操作に慣れている方々、または既存の運用ワークフローにXplentyを取り入れたい方のためにCLIベースでご利用できるRest APIを提供しています。今回の記事ではXplentyの非閲覧系のRest APIをどう活用するか詳しく見てみます。

# REST(ful) APIについて簡単な説明
順番が逆になってしまいましたが、そもそもREST APIとは何でしょうか？

他の資料を参照すると下記のように定義できます。
> RESTの原則に則って構築されたWebシステムのHTTPでの呼び出しインターフェースのこと。 REpresentational State Transferの略で、分散型システムにおける複数のソフトウェアを連携させるのに適した設計原則の集合、考え方のこと。RESTを語るうえで避けては通れない「リソース(リソース指向アーキテクチャ(ROA))」という概念がある。

では、リソースとは何でしょうか？
> Web上に存在する情報、データのこと。コンピュータ上に格納することができ、一連のビットで表現できる。また、それ自体を参照するに値するほどの重要性を持っている。例えば、ドキュメント、データベースの行等。リソースは名詞で定義される。

つまり、Webに構成されたシステム上に蓄積されたデータをリソースと言い、これらをHTTPのメソッドで操作して様々な仕事を行うことになります。操作には、リソースの作成、リソースの変更（全体、一部）、リソースの削除、リソースの閲覧があります。何らかの仕事をさせるためには、REST APIではリソースの変更（状態の変異）によってその目的を果たします。

# Rest APIの非閲覧系のメソッド
REST APIには、リソースの操作のためのメソッドが用意されており、以前の記事の全体でお見せしたのがリソースの閲覧で用いられる**GET**メソッドでした。

下記にその他のメソッドを紹介します。

|メソッド名|説明|Xplentyでの動作|
|--|--|--|
|`POST`|リソースの作成|`CREATE`で始まるAPIで使われるメソッド|
|`PUT`|リソースの全体更新（置き換え）|作成済みのリソースを変更時に使う。`UPDATE`で始まるAPIで使われるメソッド|
|`DELETE`|リソースの削除|作成済みのリソースのターミネーション（終了）する時に使う。`DELETE`で始まるAPIで使われるメソッド|
|GET|リソースの閲覧|`LIST`で始まるAPIで使われるメソッド|
|~~PATCH~~|リソースの部分更新（一部を更新）|※ Xpelntyでは使用なし|

Xplentyでは、上記のメソッドとリソースを組み合わせてデータ転送をコマンドライン上、または統合運用管理ソフトにて既存の運用環境に容易に統合ができます。

# Rest APIによる運用例
ここではXplentyのRest APIを駆使したジョブ実行の作業を説明します。普段はXplentyのUIにて行う作業ですが、Rest APIで同じ作業が可能です。
前提条件としては、作業で使われているパッケージはUIにて作成済みと想定します。

|作業|参照ドキュメント|
|--|--|
|1. クラスタの生成|[Create Cluster](https://github.com/xplenty/xplenty-api-doc-v2/blob/master/sections/create-cluster.md)|
|2. クラスタの初期化を確認|[List Clusters](https://github.com/xplenty/xplenty-api-doc-v2/blob/master/sections/list-clusters.md)|
|3. ジョブの実行|[Run Job](https://github.com/xplenty/xplenty-api-doc-v2/blob/master/sections/run-job.md)|
|4. ジョブの初期化と完了を確認|[List Jobs](https://github.com/xplenty/xplenty-api-doc-v2/blob/master/sections/list-jobs.md)|
|6. クラスタの終了|[Terminate Cluster](https://github.com/xplenty/xplenty-api-doc-v2/blob/master/sections/terminate-cluster.md)|
|7. クラスタの終了確認|[List Clusters](https://github.com/xplenty/xplenty-api-doc-v2/blob/master/sections/list-clusters.md)|


## 1. クラスタの生成
パッケージを実行するには、その実行環境であるクラスタが必要です。最初の段階ではクラスタがないと想定して、クラスタを作成します。

* Request (Curl Call) Example
```
curl -X POST -u <API_KEY>: "https://api.xplenty.com/<Account_ID>/api/clusters" \
  -H "Accept: application/vnd.xplenty+json; version=2" \
  -H "Content-Type: application/json" \
  -d '{
    "nodes":4,
    "type":"production",
    "name":"New Cluster",
    "description":"New Cluster Description"
  }'
```

* Response Example
```
HTTP/1.1 201 Created
```
```
{
  "id": 167,
  "name": "New Cluster",
  "description": "New Cluster Description",
  "status": "pending",
  "owner_id": 27,
  "plan_id": null,
  "nodes": 4,
  "type": "production",
  "created_at": "2013-03-03T13:06:51Z",
  "updated_at": "2013-03-03T13:06:51Z",
  "available_since": null,
  "terminated_at": null,
  "running_jobs_count": 0,
  "terminate_on_idle": false,
  "time_to_idol": 3600,
  "terminated_on_idle": false,
  "region": "amazon-web-services::us-east-1",
  "zone": "us-east-1b",
    :
  "idle_since": "2013-03-03T13:06:51Z",
  "url": "https://api.xplenty.com/xplenation/api/clusters/167",
  "html_url": "https://xplenty.com/xplenation/clusters/167",
  "bootstrap_actions": [{
    "script_path": "http://xplenty.s3.amazonaws.com/bootstrap-actions/file1.tar.gz",
    "args": ["arg1", "arg2"]
  }, {
    "script_path": "http://xplenty.s3.amazonaws.com/bootstrap-actions/file1.tar.gz",
    "args": ["arg1"]
  }],
  "creator": {
    "type":"Schedule",
    "display_name": "Schedule 1",
    "id":1,
    "url": "https://api.xplenty.com/xplenation/api/schedules/1",
    "html_url": "https://xplenty.com/xplenation/schedules/1"
  }
}
```

## 2. クラスタの初期化を確認
クラスタの作成と初期化を確認します。クラスタの状態(status)が **available**になるまで待つ必要があるのでこのAPIの繰り返し実行を行いましょう。

* Request (Curl Call) Example
```
curl -X GET -u <API_KEY>: "https://api.xplenty.com/<Account_ID>/api/clusters/<cluster_id>" \
  -H "Accept: application/vnd.xplenty+json; version=2"
```
* Response Example
```
HTTP/1.1 200 OK
```
```
[
  {
    "id": 99,
    "name": "Daily Outliers Test #100",
    "description": "Daily Outliers Test",
    "status": "terminated",
    "owner_id": 27,
    "plan_id": 1,
    "nodes": 2,
    "type": "production",
    "created_at": "2013-01-25T08:18:39Z",
    "updated_at": "2013-01-28T16:45:24Z",
    "available_since": "2013-01-28T16:46:22Z",
    "terminated_at": "2013-01-28T17:45:33Z",
    "running_jobs_count": 0,
    "terminate_on_idle": false,
    "time_to_idle": 3600,
    "terminated_on_idle": false,
         :
         :
    }
]
```

## 3. ジョブの実行
実行したいパッケージのpackage_idとクラスタ作成時に取得したcluster_idを用いてジョブを実行します。

* Request (Curl Call) Example

```
curl -X POST -u <API_KEY>: "https://api.xplenty.com/<Account_ID>/api/jobs" \
  -H "Accept: application/vnd.xplenty+json; version=2" \
  -H "Content-Type: application/json" \
  -d '{
    "cluster_id":167,
    "package_id":103,
    "dynamic_variables":{
      "current_time":"CurrentTime()",
      "MY_CURRENT_TIME":"$CURRENT_TIME_VAR",
      "MY_STRING_VAR":"'some string'"
    },
    "variables": {
      "MY_STATIC_VAR":"some static variable"
    }
  }'
```
* Response Example
```
HTTP/1.1 201 Created
```
```
{
  "id": 157,
  "status": "completed",
  "variables": {},
  "owner_id": 1,
  "progress": 1,
  "outputs_count": 2,
  "outputs": [
    {
      "component": {
        "name": "destination7",
        "type": "cloud_storage_destination_component",
        :
        :
      "url": "https://api.xplenty.com/xplenation/api/jobs/299/outputs/521"    },
    {
      "component": {
        "name": "destination7",
        "type": "cloud_storage_destination_component",
        "fields": [
          "id",
          "account_name"
        ]
      },
      "created_at": "2013-03-04T07:14:44Z",
      "id": 522,
          :
          :
    }
  ],
  "started_at": "2012-12-30T14:21:29Z",
  "created_at": "2012-12-30T14:21:18Z",
  "failed_at": null,
  "updated_at": "2012-12-30T14:29:29Z",
  "cluster_id": 52,
  "package_id": 434,
      :
      :
  "html_url": "https://xplenty.com/xplenation/jobs/157",
  "log_url": "https://api.xplenty.com/xplenation/api/jobs/157/log",
  "creator":
    {
      "type":"Schedule",
      "id":1,
      "display_name": "Schedule 1",
      "url": "https://api.xplenty.com/xplenation/api/schedules/1",
      "html_url": "https://xplenty.com/xplenation/schedules/1"
    }
}
```

## 4. ジョブの初期化と完了を確認
実行したジョブの`id`を用いて該当ジョブの状態(status)の遷移をモニタリングして**completed**、または**failed**になるまで このAPIの繰り返し実行を行いましょう。
ジョブの状態に対しては、[ジョブのドキュメント](https://github.com/xplenty/xplenty-api-doc-v2/blob/master/resources/job.md)の**status属性**をご参照ください。

* Request (Curl Call) Example
```
curl -X GET -u <API_KEY>: "https://api.xplenty.com/<Account_ID>/api/jobs/<job_id>" \
  -H "Accept: application/vnd.xplenty+json; version=2"
```
* Response Example
```
HTTP/1.1 200 OK
```
```
[
  {
    "id": 304,
    "status": "failed",
    "variables":
    {
        "InputPath": "'/today'"
    },
    "owner_id": 1,
    "progress": 0,
    "outputs_count": 0,
    "outputs": [],
    "started_at": "2013-03-04T08:02:20Z",
    "created_at": "2013-03-04T08:02:17Z",
    "updated_at": "2013-03-04T08:03:01Z",
    "failed_at": null,
    "cluster_id": 176,
    "package_id": 103,
    "errors": "Package failed to execute.",
    "runtime_in_seconds": 40,
    "completed_at": "2013-03-04T08:03:01Z",
    "url": "https://api.xplenty.com/xplenation/api/jobs/304",
    "html_url": "https://xplenty.com/xplenation/jobs/304",
    "log_url": "https://api.xplenty.com/xplenation/api/jobs/304/log",
    "creator":
    {
        :
        :
    },
    "package": {
      "id": 2373,
          :
          :
    },
    "cluster": {
       "id": 99,
        :
    }
  }
]
```

## 5. 続きのジョブの実行は反復
**cluster_id**と**package_id**を適切に置き換えながら手順３〜４を繰り返します。

## 6. クラスタの終了
実行対象のジョブがなくなったら、指定のクラスタを終了しましょう。

* Request (Curl Call) Example
```
curl -X DELETE -u <API_KEY>: "https://api.xplenty.com/<Account_ID>/api/clusters/<cluster_id>" \
  -H "Accept: application/vnd.xplenty+json; version=2"
```
* Response Example
```
HTTP/1.1 200 OK
```
```
{
  "id": 167,
  "name": "New Cluster",
  "description": "New Cluster Description",
  "status": "pending_terminate",
  "owner_id": 27,
  "plan_id": null,
  "nodes": 1,
  "type": "sandbox",
  "created_at": "2013-03-03T13:06:51Z",
  "updated_at": "2013-03-03T14:16:18Z",
  "available_since": "2013-03-03T13:09:22Z",
  "terminated_at": null,
  "running_jobs_count": 0,
  "terminate_on_idle": false,
    :
    :
  "bootstrap_actions": [{
    "script_path": "http://xplenty.s3.amazonaws.com/bootstrap-actions/file1.tar.gz",
    "args": ["arg1", "arg2"]
  }, {
    "script_path": "http://xplenty.s3.amazonaws.com/bootstrap-actions/file1.tar.gz",
    "args": ["arg1"]
  }],
  "creator":{
    "type":"Schedule",
    "display_name": "Schedule 1",
    "id":1,
    "url": "https://api.xplenty.com/xplenation/api/schedules/1",
    "html_url": "https://xplenty.com/xplenation/schedules/1"
  }
}
```

## 7. クラスタの終了確認
該当クラスタの状態(status)が**terminated**になるまで繰り返し実行を行います。

* Request (Curl Call) Example
```
curl -X GET -u <API_KEY>: "https://api.xplenty.com/:account_id/api/clusters/:cluster_id" \
  -H "Accept: application/vnd.xplenty+json; version=2"
```
* Response Example
```
HTTP/1.1 200 OK
```
```
[
  {
    "id": 99,
    "name": "Daily Outliers Test #100",
    "description": "Daily Outliers Test",
    "status": "terminated",
    "owner_id": 27,
    "plan_id": 1,
    "nodes": 2,
    "type": "production",
    "created_at": "2013-01-25T08:18:39Z",
    "updated_at": "2013-01-28T16:45:24Z",
    "available_since": "2013-01-28T16:46:22Z",
    "terminated_at": "2013-01-28T17:45:33Z",
    "running_jobs_count": 0,
    "terminate_on_idle": false,
    "time_to_idle": 3600,
    "terminated_on_idle": false,
         :
         :
    }
]
```

# 終わりに
以上で２回に渡ってXplentyが提供しているRest APIの機能とその使い方について紹介しました。

Rest APIを使って現行のシステムに統合したXplentyを使ってみませんか？
[２週間の無料トライアル](https://www.integrate.io/jp/demo/)にてRest APIを存分にお試し頂けます。