IBM Cloud Functionsのシーケンスを使ってアプリを実行する(コマンドを使って構築)

# はじめに
以前に投稿した記事「[IBM Cloud Functionsのシーケンスを使ってアプリを実行する](https://qiita.com/kenji_kanzaki/items/e284a2a86f334fb1e79d)」では、UIのみで作業を行いました。
本記事では上述の作業をコマンドを利用して行います。

# 前提
* IBM Cloudが提供している2022/11/16時点の機能を用いています。
* テスト用Cloudantデータベースが作成されている。
* 「[IBM Cloud FunctionsのCloudantトリガーを使ってアプリを実行する(コマンドを使って構築)](https://qiita.com/kenji_kanzaki/items/b41e02dfc074a1481aea)

# 準備
1. リンク先の手順に従って、[IBM Cloud コマンド・ライン・インターフェース (CLI)](https://cloud.ibm.com/docs/cli?topic=cli-getting-started) をインストールします。
1. リンク先の手順に従って、[Cloud Functions プラグイン](https://cloud.ibm.com/functions/learn/cli)をインストールします。
1. 2の手順に従い、IBM Cloudへのログインし名前空間のターゲットを指定します。

# Cloudantデータベースにデータを登録するシーケンスの作成
### Acionの作成
次の内容のJavascriptファイルprepareEntityForSaveCmd.jsを作成します。
```javascript:prepareEntityForSaveCmd.js
function main(params) {
  if (!params.name || !params.comment) {
    return Promise.reject({ error: 'no name or comment'});
  }

  return {
    doc: {
      createdAt: new Date(),
       name: params.name,
       email: params.email,
       comment: params.comment
    }
  };
}
```
Javascriptファイルからアクションを作成します。
```shell:
ibmcloud fn action create prepareEntityForSaveCmd prepareEntityForSaveCmd.js
```
```
ok: created action prepareEntityForSaveCmd
```

アクションの一覧を表示し、作成した3アクションが作成されていることを確認します。
```shell:
ibmcloud fn action list
```
~~~
actions
<NAMESPACE>/prepareEntityForSaveCmd                       private nodejs:16
~~~

### シーケンスの作成
以下の順番にActionが実行されるシーケンスSaveEntitySequenceCmdを作成します。
1. 上述で作成したprepareEntityForSaveCmd
1. 「[IBM Cloud FunctionsのCloudantトリガーを使ってアプリを実行する(コマンドを使って構築)](https://qiita.com/kenji_kanzaki/items/b41e02dfc074a1481aea)でバインドしたパッケージsampleCloudantに含まれるcreate-document Action

```shell:
ibmcloud fn action create SaveEntitySequenceCmd --sequence prepareEntityForSaveCmd,sampleCloudant/create-document
```
~~~
ok: created action SaveEntitySequenceCmd
~~~
シーケンスが作成されたことを確認します。
```shell:
ibmcloud fn action list
```
~~~
actions
<NAMESPACE>/SaveEntitySequenceCmd                         private sequence
~~~

### 稼働確認
作成したシーケンスが稼働し、データが登録されることを確認します。
```shell:
ibmcloud fn action invoke SaveEntitySequenceCmd -p name "Taro Tanaka" -p email "taro@sample.com" -p comment "this is Taro's comment."
```
~~~
ok: invoked /_/SaveEntitySequenceCmd with id XXXXXXXXXXXXXXXXXXXXXXX
~~~
アクティベーションログを確認します。
```shell:
ibmcloud fn activation list
```
~~~
Datetime            Activation ID                    Kind      Start Duration   Status            Entity
2022-11-22 22:47:31 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX nodejs:12 cold  1.001s     success           <NAMESPACE>/create-document:0.0.548
2022-11-22 22:47:31 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX nodejs:16 cold  34ms       success           <NAMESPACE>/prepareEntityForSaveCmd:0.0.1
2022-11-22 22:47:31 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX sequence  warm  1.267s     success           <NAMESPACE>/SaveEntitySequenceCmd:0.0.1
~~~
シーケンスと各Actionが実行されていることが確認できました。
念のためCloudantにデータが登録されていることを画面から確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2073396/fe7a70f1-e27e-a665-77c1-da9e53a20dd4.png)




# Cloudantデータベースのデータを参照するシーケンスの作成
### Acionの作成
Actionを2つ作成します。
1つ目のActionを作成します。次の内容のJavascriptファイルsetResultInputCmd.jsを作成します。
```javascript:setResultInputCmd.js
function main(params) {
  return {
    params: {
      include_docs: true
    }
  };
}
```
Javascriptファイルからアクションを作成します。
```shell:
ibmcloud fn action create setResultInputCmd setResultInputCmd.js
```
```
ok: created action setResultInputCmd
```

2つ目のActionを作成します。次の内容のJavascriptファイルformatEntityCmd.jsを作成します。
```javascript:formatEntityCmd.js
const md5 = require('spark-md5');

function main(params) {
  return {
    entries: params.rows.map((row) => { return {
      name: row.doc.name,
      email: row.doc.email,
      comment: row.doc.comment,
      createdAt: row.doc.createdAt,
      icon: (row.doc.email ? `https://secure.gravatar.com/avatar/${md5.hash(row.doc.email.trim().toLowerCase())}?s=64` : null)
    }})
  };
}
```
Javascriptファイルからアクションを作成します。
```shell:
ibmcloud fn action create formatEntityCmd formatEntityCmd.js
```
```
ok: created action formatEntityCmd
```
アクションの一覧を表示し、作成したアクションが作成されていることを確認します。
```shell:
ibmcloud fn action list
```
```shell:
actions
<NAMESPACE>/formatEntityCmd                               private nodejs:16
<NAMESPACE>/setResultInputCmd                             private nodejs:16
```

### シーケンスの作成
以下の順番にActionが実行されるシーケンスReadEntitySequenceCmdを作成します。
1. 上述で作成したsetResultInputCmd
1. 「[IBM Cloud FunctionsのCloudantトリガーを使ってアプリを実行する(コマンドを使って構築)](https://qiita.com/kenji_kanzaki/items/b41e02dfc074a1481aea)でバインドしたパッケージsampleCloudantに含まれるlist-documents Action
1. 上述で作成したformatEntityCmd  

```shell:
ibmcloud fn action create ReadEntitySequenceCmd --sequence setResultInputCmd,sampleCloudant/list-documents,formatEntityCmd
```
~~~
ok: created action ReadEntitySequenceCmd
~~~
シーケンスが作成されたことを確認します。
```shell:
ibmcloud fn action list
```
~~~
actions
<NAMESPACE>/ReadEntitySequenceCmd                         private sequence
~~~

### 稼働確認
作成したシーケンスが稼働し、データが参照できることを確認します。
```shell:
ibmcloud fn action invoke ReadEntitySequenceCmd -r
```
~~~
{
    "entries": [
        {
            "comment": "this is Hanako's comment",
            "createdAt": "2022-08-30T12:00:17.584Z",
            "email": "hanako@sample.com",
            "icon": "https://secure.gravatar.com/avatar/190f9f022b4bfb762e152f1c3d6dd35a?s=64",
            "name": "Hanako Suzuki"
        },
        {
            "comment": "this is Taro's comment.",
            "createdAt": "2022-11-22T13:47:31.157Z",
            "email": "taro@sample.com",
            "icon": "https://secure.gravatar.com/avatar/4179319e919e011a1aec1ca4d34100b1?s=64",
            "name": "Taro Tanaka"
        }
    ]
}
~~~
SaveEntitySequenceCmdを実行し登録されたデータが含まれたデータが取得できました。
次にアクティベーションログを確認します。
```shell:
ibmcloud fn activation list
```
~~~
Datetime            Activation ID                    Kind      Start Duration   Status            Entity
2022-11-22 23:04:15 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX nodejs:16 cold  32ms       success           <NAMESPACE>/formatEntityCmd:0.0.1
2022-11-22 23:04:13 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX nodejs:12 cold  1.994s     success           <NAMESPACE>/list-documents:0.0.547
2022-11-22 23:04:13 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX nodejs:16 cold  68ms       success           <NAMESPACE>/setResultInputCmd:0.0.1
2022-11-22 23:04:13 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX sequence  warm  2.315s     success           <NAMESPACE>/ReadEntitySequenceCmd:0.0.1
~~~
シーケンスと各Actionが実行されていることが確認できました。