読める！読めるぞ！リーダブルフロー


## はじめに

Node-REDの読みやすいフローを目指して、Tipsをまとめました。
機会があればイベントとかでも発表したいな。

フロー書いてたら、ごちゃーってなってスパゲッティフローになることありませんか？
動いてるからいいやーってそのままにして、数ヶ月後に改造しようとしたときになんだこれは！！ってなったことありませんか？
他の人が書いたフローをちょちょっと改造して、楽勝！と思っていたら、フローがどこで何してるかわからなくて困ったことありませんか？
私はあります！！

そんな困った事にならないように、自分のため、みんなのためにわかりやすいフローを書きたい！
そんな気持ちから、書き始めました。

かなり自己流な部分もあるので、こんなやり方もあるよ！とかこっちの方がいいよ！とかあれば、ぜひ教えてください！

## ■名前付け
### ノードの名前

名前を設定すると何をしているのか、わかりやすくなります。
処理名や何をしている（したい）かを書く。

入力前
![スクリーンショット 2021-12-02 0.39.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128077/8fa8402b-3408-ef11-33bb-bba10ca48bc9.png)

入力後
![スクリーンショット 2021-12-02 0.39.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128077/dccee9db-17e0-dfec-be4c-98f53a2e9246.png)

以下のようなメリットもあります。

- debugノード：デバッグ画面でノードIDが名前になる

![デバッグタイトル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128077/ac912d2b-9874-2739-30b2-eea1e09817b6.png)


- Linkノード：リンク先、元のノードIDが名前になる
  
![スクリーンショット 2021-12-02 0.49.08 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128077/ed39e87a-bb5b-eab7-b083-9db598c12113.png)
![スクリーンショット 2021-12-02 0.49.19 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128077/994ed0b5-17a0-8f8e-6f00-ea67064e8a13.png)


### コメントノード

処理のまとまりをコメントノードで示すとわかりやすい。
仕様をMarkdownで記入すれば「情報」サイドパネルに表示されます。

![コメント.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128077/f91d10ed-d859-8eac-3b66-1a082ac56861.png)

## ■構造化

### ノードの流れ

- 左から右に
    - ワイヤーがまっすぐになるようにしたほうが読みやすい。
- 上から下に
    - 右端が画面に収まらなくなったら折り返す。ワイヤーが画面からはみ出ないようにする。
![スクリーンショット 2021-12-06 20.23.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128077/12a867b9-2649-6f5c-6ec4-64a003d10fd5.png)

選択したノードを一気に整列したい場合は、メニューの配置機能も便利です。

### functionノードでコネクター

複数の処理が合流するときにワイヤーを遠くに何本も接続すると、ワイヤーが多くてわかりにくくなります。
そこで、何も処理しないfunctionノードをコネクターにするとワイヤーを1本にまとめられて、見た目がスッキリします。
ノードの繋ぎ変えも1本で済んで便利！

改善前
![スクリーンショット 2021-12-04 9.32.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128077/9544a761-fb32-6b0f-e302-05586e11effc.png)

改善後
![スクリーンショット 2021-12-04 9.32.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128077/ae9ee5ca-12cd-e09f-4e6b-dcd9f6f205e9.png)

### Linkノードで処理を分割する

以下のような場合はLinkノードを使用すると見た目がスッキリします。
また、どこへ接続しているかをコメントノードを付けるとわかりやすくなります。

- 複数の処理から、または、複数の処理へ接続
- 遠くへの接続

改善前
![リンク前.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128077/6cf91796-d1fd-c2b5-c5ae-0bf76ff249a3.png)
改善後
![リンク後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128077/1f631ba3-a90f-e853-d6b7-59725cc2fda5.png)


### サブフローで処理を分割する

DRY原則（Don't Repeat Yourself）

1つの処理にまとめられる。
msg変数でパラメータを渡して汎用化できる。

以下のような場合に有効

- 複数箇所で呼ばれる処理
- 似たような処理をいくつも書く

![スクリーンショット 2021-12-06 20.23.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128077/d7fc6391-5bea-2bec-b38e-4523e1e4bf17.png)
修正は1箇所でOKになった！
![スクリーンショット 2021-12-06 20.23.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128077/c1d958e9-e216-ef51-1fe6-b792b3712f82.png)

### switchノード

- 名前をつける。「〇〇判定」「閾値超過?」
- boolの判定は上をtrueにすることが多いです。（文脈による）

## ■functionノード

コードを書かずにプログラムできるのがNode-REDの特徴の1つですが、JavaScriptを書けるならfunctionノードを適材適所で活用できると思います。

### functionノードで処理をまとめる

changeノードやswitchノード等を複数使用して、ちょっとした処理を書くことも多いと思いますが、何してるかまで見えなくてもいい場合、functionノードにまとめるのもいいかもしれません。
ノード数が少なくなりフローがシンプルになることで、重要なビジネスロジックに集中できます！

- こんな時に使える
  - 細々とした見えなくてもいい処理
  - 1つのまとまった処理
- こんな時は向いてないかも
  - 保守する人がJavaScriptを使えない

![スクリーンショット 2021-12-06 20.54.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128077/1c70ff31-8961-686c-b46b-c292262ef21c.png)
![スクリーンショット 2021-12-06 20.54.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128077/6ec95926-b17f-e944-9559-2617a8080d31.png)

### functionノードの処理を分割する

functionノード便利！！！全部functionノードでやっちゃおう！！
ってすると、数百行の何してるかわからないfunctionノードができて詰む。
みたいな事もありますね。

1つのfunctionにはノード名で表せる1つの仕事をさせるようにしましょう。
フローを見て「何がしたいのかがわかる」、「伝えたいことが伝わる」のが重要だと思います。

![スクリーンショット 2021-12-06 21.14.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128077/d83d82ba-926a-7e15-c179-47e979a1b368.png)

### functionの出力先の定数化

出力を増やした時、
1つ目の出力は`return msg;`
2つ目は`return [null, msg];`
3つ目は`return [null, null, msg];`
ってと書きますが、これが読みにくい。

- 何個目に出力しているか数えないといけない
- 出力先の一括変更ができない

なので、これを定数化したい。

改善前

``` js
if(isHoge){
    return msg;
}else if(isHuga){
    return [null, msg];
}else if(isPiyo){
    return [null, null, msg];
}else{
    return msg;
}
```

改善後
nullの配列を作って最後にmsgをつなげています。

``` js
// アウトプット
const OUT_HOGE = 0;
const OUT_HUGA = 1;
const OUT_PIYO = 2;

if(isHoge){
    return Array(OUT_HOGE).fill(null).concat(msg);
}else if(isHuga){
    return Array(OUT_HUGA).fill(null).concat(msg);
}else if(isPiyo){
    return Array(OUT_PIYO).fill(null).concat(msg);
}else{
    return Array(OUT_HOGE).fill(null).concat(msg);
}
```

## ■その他tips

### グローバルな関数

[Node-RED TIPS：functionノード間で関数を共有する方法](https://www.slideshare.net/kazukisaito127/nodered-tipsfunction)
をよく使っています。

Node-REDのバージョンアップで、今はモジュールをインポートできるようになっている？
（functionノードのモジュール機能まだ使ったことがない。。。）
いいやり方があったら教えてください。

### msg汚染問題

msg変数にプロパティが増えていく問題。
後で使うので、payloadをmsg.hogeにバックアップして、デバッグ用にmsg.hugaにこれを保存して・・・
デバッグログで確認すると、うわー。見たい情報どこだよ！！必要な情報はどれ？？ってよくなります。

こんな時は、以下のような対策をよく使います。

- msgに保存せずにfunctionノード内のローカル変数にする
- フロー変数、グローバル変数にする。（長いフローの一部でしか使わない場合）
- 使用しなくなったら、すぐに削除
    - Changeノードで「値の削除」
    - functionノードで
        - プロパティ指定で削除：`delete msg.hoge;`
        - 全部削除 msgの初期化：`msg = {};`
        - 一部残す：

``` js
const newMsg = {};

newMsg.payloag = msg.payloag;
newMsg.data = msg.data;

msg = newMsg;

return msg;
```

### デバッグTips
- 変数確認
changeノードでflow変数、global変数をmsgにコピしてdebugノードで確認。
これでフロー中のデバッグノードの数が減らせます。
![スクリーンショット 2021-12-06 22.13.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128077/7bcdc47d-183b-de33-4850-e90ab93ecc38.png)

追記：サイドバーの「コンテキストデータ」からも確認できますね。

- catchノードで例外捕捉
本番環境で、例外ログを残したりメールで例外通知すると、記録を残せます。攻めのデバッグ！
![例外捕捉.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128077/fe916285-7a80-35a4-2bea-3474054f13a3.png)

## 参考
以下の記事も参考になります。
他にもいい記事、ドキュメントあればコメントで教えてください。

- [目からウロコ！Node\-REDのデザインパターン10選 \- Qiita](https://qiita.com/zuhito/items/e9abfd6f1ba188f908ed)
- [目からウロコ！Node\-REDのアンチパターン10選 \- Qiita](https://qiita.com/zuhito/items/442a8b99c597150f8472)

## さいごに

[弊社(ユニロボット)](https://www.unirobot.com/)では、フローの開発、Node-REDの改造、独自ノードの開発等を行なっています。
絶賛エンジニアを募集中です！他にもいろんなレイヤーの開発があります。
我こそは！！という方は、[弊社採用ページ](https://www.unirobot.com/recruit/)をご覧ください！